1 /* 2 * SPDX-License-Identifier: BSD-3-Clause 3 * Copyright(c) 2023 Napatech A/S 4 */ 5 6 #ifndef _FLOW_API_ENGINE_H_ 7 #define _FLOW_API_ENGINE_H_ 8 9 #include <stdint.h> 10 #include <stdatomic.h> 11 12 #include "hw_mod_backend.h" 13 #include "stream_binary_flow_api.h" 14 15 /* 16 * Resource management 17 */ 18 #define BIT_CONTAINER_8_ALIGN(x) (((x) + 7) / 8) 19 20 /* 21 * Resource management 22 * These are free resources in FPGA 23 * Other FPGA memory lists are linked to one of these 24 * and will implicitly follow them 25 */ 26 enum res_type_e { 27 RES_QUEUE, 28 RES_CAT_CFN, 29 RES_CAT_COT, 30 RES_CAT_EXO, 31 RES_CAT_LEN, 32 RES_KM_FLOW_TYPE, 33 RES_KM_CATEGORY, 34 RES_HSH_RCP, 35 RES_PDB_RCP, 36 RES_QSL_RCP, 37 RES_QSL_QST, 38 RES_SLC_LR_RCP, 39 40 RES_FLM_FLOW_TYPE, 41 RES_FLM_RCP, 42 RES_TPE_RCP, 43 RES_TPE_EXT, 44 RES_TPE_RPL, 45 RES_SCRUB_RCP, 46 RES_COUNT, 47 RES_INVALID 48 }; 49 50 /* 51 * Flow NIC offload management 52 */ 53 #define MAX_OUTPUT_DEST (128) 54 55 #define MAX_WORD_NUM 24 56 #define MAX_BANKS 6 57 58 #define MAX_TCAM_START_OFFSETS 4 59 60 #define MAX_FLM_MTRS_SUPPORTED 4 61 #define MAX_CPY_WRITERS_SUPPORTED 8 62 63 #define MAX_MATCH_FIELDS 16 64 65 /* 66 * 128 128 32 32 32 67 * Have | QW0 || QW4 || SW8 || SW9 | SWX in FPGA 68 * 69 * Each word may start at any offset, though 70 * they are combined in chronological order, with all enabled to 71 * build the extracted match data, thus that is how the match key 72 * must be build 73 */ 74 enum extractor_e { 75 KM_USE_EXTRACTOR_UNDEF, 76 KM_USE_EXTRACTOR_QWORD, 77 KM_USE_EXTRACTOR_SWORD, 78 }; 79 80 struct match_elem_s { 81 enum extractor_e extr; 82 int masked_for_tcam; /* if potentially selected for TCAM */ 83 uint32_t e_word[4]; 84 uint32_t e_mask[4]; 85 86 int extr_start_offs_id; 87 int8_t rel_offs; 88 uint32_t word_len; 89 }; 90 91 enum cam_tech_use_e { 92 KM_CAM, 93 KM_TCAM, 94 KM_SYNERGY 95 }; 96 97 struct km_flow_def_s { 98 struct flow_api_backend_s *be; 99 100 /* For keeping track of identical entries */ 101 struct km_flow_def_s *reference; 102 struct km_flow_def_s *root; 103 104 /* For collect flow elements and sorting */ 105 struct match_elem_s match[MAX_MATCH_FIELDS]; 106 struct match_elem_s *match_map[MAX_MATCH_FIELDS]; 107 int num_ftype_elem; 108 109 /* Finally formatted CAM/TCAM entry */ 110 enum cam_tech_use_e target; 111 uint32_t entry_word[MAX_WORD_NUM]; 112 uint32_t entry_mask[MAX_WORD_NUM]; 113 int key_word_size; 114 115 /* TCAM calculated possible bank start offsets */ 116 int start_offsets[MAX_TCAM_START_OFFSETS]; 117 int num_start_offsets; 118 119 /* Flow information */ 120 /* HW input port ID needed for compare. In port must be identical on flow types */ 121 uint32_t port_id; 122 uint32_t info; /* used for color (actions) */ 123 int info_set; 124 int flow_type; /* 0 is illegal and used as unset */ 125 int flushed_to_target; /* if this km entry has been finally programmed into NIC hw */ 126 127 /* CAM specific bank management */ 128 int cam_paired; 129 int record_indexes[MAX_BANKS]; 130 int bank_used; 131 uint32_t *cuckoo_moves; /* for CAM statistics only */ 132 struct cam_distrib_s *cam_dist; 133 struct hasher_s *hsh; 134 135 /* TCAM specific bank management */ 136 struct tcam_distrib_s *tcam_dist; 137 int tcam_start_bank; 138 int tcam_record; 139 }; 140 141 /* 142 * RSS configuration, see struct rte_flow_action_rss 143 */ 144 struct hsh_def_s { 145 enum rte_eth_hash_function func; /* RSS hash function to apply */ 146 /* RSS hash types, see definition of RTE_ETH_RSS_* for hash calculation options */ 147 uint64_t types; 148 uint32_t key_len; /* Hash key length in bytes. */ 149 const uint8_t *key; /* Hash key. */ 150 }; 151 152 /* 153 * AGE configuration, see struct rte_flow_action_age 154 */ 155 struct age_def_s { 156 uint32_t timeout; 157 void *context; 158 }; 159 160 /* 161 * Tunnel encapsulation header definition 162 */ 163 #define MAX_TUN_HDR_SIZE 128 164 165 struct tunnel_header_s { 166 union { 167 uint8_t hdr8[MAX_TUN_HDR_SIZE]; 168 uint32_t hdr32[(MAX_TUN_HDR_SIZE + 3) / 4]; 169 } d; 170 171 uint8_t len; 172 173 uint8_t nb_vlans; 174 175 uint8_t ip_version; /* 4: v4, 6: v6 */ 176 177 uint8_t new_outer; 178 uint8_t l2_len; 179 uint8_t l3_len; 180 uint8_t l4_len; 181 }; 182 183 enum flow_port_type_e { 184 PORT_NONE, /* not defined or drop */ 185 PORT_INTERNAL, /* no queues attached */ 186 PORT_PHY, /* MAC phy output queue */ 187 PORT_VIRT, /* Memory queues to Host */ 188 }; 189 190 struct output_s { 191 uint32_t owning_port_id;/* the port who owns this output destination */ 192 enum flow_port_type_e type; 193 int id; /* depending on port type: queue ID or physical port id or not used */ 194 int active; /* activated */ 195 }; 196 197 struct nic_flow_def { 198 /* 199 * Frame Decoder match info collected 200 */ 201 int l2_prot; 202 int l3_prot; 203 int l4_prot; 204 int tunnel_prot; 205 int tunnel_l3_prot; 206 int tunnel_l4_prot; 207 int vlans; 208 int fragmentation; 209 int ip_prot; 210 int tunnel_ip_prot; 211 /* 212 * Additional meta data for various functions 213 */ 214 int in_port_override; 215 int non_empty; /* default value is -1; value 1 means flow actions update */ 216 struct output_s dst_id[MAX_OUTPUT_DEST];/* define the output to use */ 217 /* total number of available queues defined for all outputs - i.e. number of dst_id's */ 218 int dst_num_avail; 219 220 /* 221 * Mark or Action info collection 222 */ 223 uint32_t mark; 224 225 uint32_t jump_to_group; 226 227 uint32_t mtr_ids[MAX_FLM_MTRS_SUPPORTED]; 228 229 int full_offload; 230 231 /* 232 * Action push tunnel 233 */ 234 struct tunnel_header_s tun_hdr; 235 236 /* 237 * If DPDK RTE tunnel helper API used 238 * this holds the tunnel if used in flow 239 */ 240 struct tunnel_s *tnl; 241 242 /* 243 * Header Stripper 244 */ 245 int header_strip_end_dyn; 246 int header_strip_end_ofs; 247 248 /* 249 * Modify field 250 */ 251 struct { 252 uint32_t select; 253 uint32_t dyn; 254 uint32_t ofs; 255 uint32_t len; 256 uint32_t level; 257 union { 258 uint8_t value8[16]; 259 uint16_t value16[8]; 260 uint32_t value32[4]; 261 }; 262 } modify_field[MAX_CPY_WRITERS_SUPPORTED]; 263 264 uint32_t modify_field_count; 265 uint8_t ttl_sub_enable; 266 uint8_t ttl_sub_ipv4; 267 uint8_t ttl_sub_outer; 268 269 /* 270 * Key Matcher flow definitions 271 */ 272 struct km_flow_def_s km; 273 274 /* 275 * Hash module RSS definitions 276 */ 277 struct hsh_def_s hsh; 278 279 /* 280 * AGE action timeout 281 */ 282 struct age_def_s age; 283 284 /* 285 * TX fragmentation IFR/RPP_LR MTU recipe 286 */ 287 uint8_t flm_mtu_fragmentation_recipe; 288 }; 289 290 enum flow_handle_type { 291 FLOW_HANDLE_TYPE_FLOW, 292 FLOW_HANDLE_TYPE_FLM, 293 }; 294 295 struct flow_handle { 296 enum flow_handle_type type; 297 uint32_t flm_id; 298 uint16_t caller_id; 299 uint16_t learn_ignored; 300 301 struct flow_eth_dev *dev; 302 struct flow_handle *next; 303 struct flow_handle *prev; 304 305 /* Flow specific pointer to application data stored during action creation. */ 306 void *context; 307 void *user_data; 308 309 union { 310 struct { 311 /* 312 * 1st step conversion and validation of flow 313 * verified and converted flow match + actions structure 314 */ 315 struct nic_flow_def *fd; 316 /* 317 * 2nd step NIC HW resource allocation and configuration 318 * NIC resource management structures 319 */ 320 struct { 321 uint32_t db_idx_counter; 322 uint32_t db_idxs[RES_COUNT]; 323 }; 324 uint32_t port_id; /* MAC port ID or override of virtual in_port */ 325 }; 326 327 struct { 328 uint32_t flm_db_idx_counter; 329 uint32_t flm_db_idxs[RES_COUNT]; 330 331 uint32_t flm_mtr_ids[MAX_FLM_MTRS_SUPPORTED]; 332 333 uint32_t flm_data[10]; 334 uint8_t flm_prot; 335 uint8_t flm_kid; 336 uint8_t flm_prio; 337 uint8_t flm_ft; 338 339 uint16_t flm_rpl_ext_ptr; 340 uint32_t flm_nat_ipv4; 341 uint16_t flm_nat_port; 342 uint8_t flm_dscp; 343 uint32_t flm_teid; 344 uint8_t flm_rqi; 345 uint8_t flm_qfi; 346 uint8_t flm_scrub_prof; 347 348 uint8_t flm_mtu_fragmentation_recipe; 349 350 /* Flow specific pointer to application template table cell stored during 351 * flow create. 352 */ 353 struct flow_template_table_cell *template_table_cell; 354 bool flm_async; 355 }; 356 }; 357 }; 358 359 struct flow_pattern_template { 360 struct nic_flow_def *fd; 361 }; 362 363 struct flow_actions_template { 364 struct nic_flow_def *fd; 365 366 uint32_t num_dest_port; 367 uint32_t num_queues; 368 }; 369 370 struct flow_template_table_cell { 371 atomic_int status; 372 atomic_int counter; 373 374 uint32_t flm_db_idx_counter; 375 uint32_t flm_db_idxs[RES_COUNT]; 376 377 uint32_t flm_key_id; 378 uint32_t flm_ft; 379 380 uint16_t flm_rpl_ext_ptr; 381 uint8_t flm_scrub_prof; 382 }; 383 384 struct flow_template_table { 385 struct flow_pattern_template **pattern_templates; 386 uint8_t nb_pattern_templates; 387 388 struct flow_actions_template **actions_templates; 389 uint8_t nb_actions_templates; 390 391 struct flow_template_table_cell *pattern_action_pairs; 392 393 struct rte_flow_attr attr; 394 uint16_t forced_vlan_vid; 395 uint16_t caller_id; 396 }; 397 398 void km_attach_ndev_resource_management(struct km_flow_def_s *km, void **handle); 399 void km_free_ndev_resource_management(void **handle); 400 401 int km_add_match_elem(struct km_flow_def_s *km, uint32_t e_word[4], uint32_t e_mask[4], 402 uint32_t word_len, enum frame_offs_e start, int8_t offset); 403 404 int km_key_create(struct km_flow_def_s *km, uint32_t port_id); 405 /* 406 * Compares 2 KM key definitions after first collect validate and optimization. 407 * km is compared against an existing km1. 408 * if identical, km1 flow_type is returned 409 */ 410 int km_key_compare(struct km_flow_def_s *km, struct km_flow_def_s *km1); 411 412 int km_rcp_set(struct km_flow_def_s *km, int index); 413 414 int km_write_data_match_entry(struct km_flow_def_s *km, uint32_t color); 415 int km_clear_data_match_entry(struct km_flow_def_s *km); 416 417 void kcc_free_ndev_resource_management(void **handle); 418 419 /* 420 * Group management 421 */ 422 int flow_group_handle_create(void **handle, uint32_t group_count); 423 int flow_group_handle_destroy(void **handle); 424 425 int flow_group_translate_get(void *handle, uint8_t owner_id, uint8_t port_id, uint32_t group_in, 426 uint32_t *group_out); 427 428 #endif /* _FLOW_API_ENGINE_H_ */ 429