/* * SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2023 Napatech A/S */ #ifndef _FLOW_API_ENGINE_H_ #define _FLOW_API_ENGINE_H_ #include #include #include "hw_mod_backend.h" #include "stream_binary_flow_api.h" /* * Resource management */ #define BIT_CONTAINER_8_ALIGN(x) (((x) + 7) / 8) /* * Resource management * These are free resources in FPGA * Other FPGA memory lists are linked to one of these * and will implicitly follow them */ enum res_type_e { RES_QUEUE, RES_CAT_CFN, RES_CAT_COT, RES_CAT_EXO, RES_CAT_LEN, RES_KM_FLOW_TYPE, RES_KM_CATEGORY, RES_HSH_RCP, RES_PDB_RCP, RES_QSL_RCP, RES_QSL_QST, RES_SLC_LR_RCP, RES_FLM_FLOW_TYPE, RES_FLM_RCP, RES_TPE_RCP, RES_TPE_EXT, RES_TPE_RPL, RES_SCRUB_RCP, RES_COUNT, RES_INVALID, RES_END }; /* * Flow NIC offload management */ #define MAX_OUTPUT_DEST (128) #define MAX_WORD_NUM 24 #define MAX_BANKS 6 #define MAX_TCAM_START_OFFSETS 4 #define MAX_FLM_MTRS_SUPPORTED 4 #define MAX_CPY_WRITERS_SUPPORTED 8 #define MAX_MATCH_FIELDS 16 /* * 128 128 32 32 32 * Have | QW0 || QW4 || SW8 || SW9 | SWX in FPGA * * Each word may start at any offset, though * they are combined in chronological order, with all enabled to * build the extracted match data, thus that is how the match key * must be build */ enum extractor_e { KM_USE_EXTRACTOR_UNDEF, KM_USE_EXTRACTOR_QWORD, KM_USE_EXTRACTOR_SWORD, }; struct match_elem_s { enum extractor_e extr; int masked_for_tcam; /* if potentially selected for TCAM */ uint32_t e_word[4]; uint32_t e_mask[4]; int extr_start_offs_id; int8_t rel_offs; uint32_t word_len; }; enum cam_tech_use_e { KM_CAM, KM_TCAM, KM_SYNERGY }; struct km_flow_def_s { struct flow_api_backend_s *be; /* For keeping track of identical entries */ struct km_flow_def_s *reference; struct km_flow_def_s *root; /* For collect flow elements and sorting */ struct match_elem_s match[MAX_MATCH_FIELDS]; struct match_elem_s *match_map[MAX_MATCH_FIELDS]; int num_ftype_elem; /* Finally formatted CAM/TCAM entry */ enum cam_tech_use_e target; uint32_t entry_word[MAX_WORD_NUM]; uint32_t entry_mask[MAX_WORD_NUM]; int key_word_size; /* TCAM calculated possible bank start offsets */ int start_offsets[MAX_TCAM_START_OFFSETS]; int num_start_offsets; /* Flow information */ /* HW input port ID needed for compare. In port must be identical on flow types */ uint32_t port_id; uint32_t info; /* used for color (actions) */ int info_set; int flow_type; /* 0 is illegal and used as unset */ int flushed_to_target; /* if this km entry has been finally programmed into NIC hw */ /* CAM specific bank management */ int cam_paired; int record_indexes[MAX_BANKS]; int bank_used; uint32_t *cuckoo_moves; /* for CAM statistics only */ struct cam_distrib_s *cam_dist; struct hasher_s *hsh; /* TCAM specific bank management */ struct tcam_distrib_s *tcam_dist; int tcam_start_bank; int tcam_record; }; /* * RSS configuration, see struct rte_flow_action_rss */ struct hsh_def_s { enum rte_eth_hash_function func; /* RSS hash function to apply */ /* RSS hash types, see definition of RTE_ETH_RSS_* for hash calculation options */ uint64_t types; uint32_t key_len; /* Hash key length in bytes. */ const uint8_t *key; /* Hash key. */ }; /* * AGE configuration, see struct rte_flow_action_age */ struct age_def_s { uint32_t timeout; void *context; }; /* * Tunnel encapsulation header definition */ #define MAX_TUN_HDR_SIZE 128 struct tunnel_header_s { union { uint8_t hdr8[MAX_TUN_HDR_SIZE]; uint32_t hdr32[(MAX_TUN_HDR_SIZE + 3) / 4]; } d; uint8_t len; uint8_t nb_vlans; uint8_t ip_version; /* 4: v4, 6: v6 */ uint8_t new_outer; uint8_t l2_len; uint8_t l3_len; uint8_t l4_len; }; enum flow_port_type_e { PORT_NONE, /* not defined or drop */ PORT_INTERNAL, /* no queues attached */ PORT_PHY, /* MAC phy output queue */ PORT_VIRT, /* Memory queues to Host */ }; struct output_s { uint32_t owning_port_id;/* the port who owns this output destination */ enum flow_port_type_e type; int id; /* depending on port type: queue ID or physical port id or not used */ int active; /* activated */ }; struct nic_flow_def { /* * Frame Decoder match info collected */ int l2_prot; int l3_prot; int l4_prot; int tunnel_prot; int tunnel_l3_prot; int tunnel_l4_prot; int vlans; int fragmentation; int ip_prot; int tunnel_ip_prot; /* * Additional meta data for various functions */ int in_port_override; int non_empty; /* default value is -1; value 1 means flow actions update */ struct output_s dst_id[MAX_OUTPUT_DEST];/* define the output to use */ /* total number of available queues defined for all outputs - i.e. number of dst_id's */ int dst_num_avail; /* * Mark or Action info collection */ uint32_t mark; uint32_t jump_to_group; uint32_t mtr_ids[MAX_FLM_MTRS_SUPPORTED]; int full_offload; /* * Action push tunnel */ struct tunnel_header_s tun_hdr; /* * If DPDK RTE tunnel helper API used * this holds the tunnel if used in flow */ struct tunnel_s *tnl; /* * Header Stripper */ int header_strip_end_dyn; int header_strip_end_ofs; /* * Modify field */ struct { uint32_t select; uint32_t dyn; uint32_t ofs; uint32_t len; uint32_t level; union { uint8_t value8[16]; uint16_t value16[8]; uint32_t value32[4]; }; } modify_field[MAX_CPY_WRITERS_SUPPORTED]; uint32_t modify_field_count; uint8_t ttl_sub_enable; uint8_t ttl_sub_ipv4; uint8_t ttl_sub_outer; /* * Key Matcher flow definitions */ struct km_flow_def_s km; /* * Hash module RSS definitions */ struct hsh_def_s hsh; /* * AGE action timeout */ struct age_def_s age; /* * TX fragmentation IFR/RPP_LR MTU recipe */ uint8_t flm_mtu_fragmentation_recipe; }; enum flow_handle_type { FLOW_HANDLE_TYPE_FLOW, FLOW_HANDLE_TYPE_FLM, }; struct flow_handle { enum flow_handle_type type; uint32_t flm_id; uint16_t caller_id; uint16_t learn_ignored; struct flow_eth_dev *dev; struct flow_handle *next; struct flow_handle *prev; /* Flow specific pointer to application data stored during action creation. */ void *context; void *user_data; union { struct { /* * 1st step conversion and validation of flow * verified and converted flow match + actions structure */ struct nic_flow_def *fd; /* * 2nd step NIC HW resource allocation and configuration * NIC resource management structures */ struct { uint32_t db_idx_counter; uint32_t db_idxs[RES_COUNT]; }; uint32_t port_id; /* MAC port ID or override of virtual in_port */ }; struct { uint32_t flm_db_idx_counter; uint32_t flm_db_idxs[RES_COUNT]; uint32_t flm_mtr_ids[MAX_FLM_MTRS_SUPPORTED]; uint32_t flm_data[10]; uint8_t flm_prot; uint8_t flm_kid; uint8_t flm_prio; uint8_t flm_ft; uint16_t flm_rpl_ext_ptr; uint32_t flm_nat_ipv4; uint16_t flm_nat_port; uint8_t flm_dscp; uint32_t flm_teid; uint8_t flm_rqi; uint8_t flm_qfi; uint8_t flm_scrub_prof; uint8_t flm_mtu_fragmentation_recipe; /* Flow specific pointer to application template table cell stored during * flow create. */ struct flow_template_table_cell *template_table_cell; bool flm_async; }; }; }; struct flow_pattern_template { struct nic_flow_def *fd; }; struct flow_actions_template { struct nic_flow_def *fd; uint32_t num_dest_port; uint32_t num_queues; }; struct flow_template_table_cell { atomic_int status; atomic_int counter; uint32_t flm_db_idx_counter; uint32_t flm_db_idxs[RES_COUNT]; uint32_t flm_key_id; uint32_t flm_ft; uint16_t flm_rpl_ext_ptr; uint8_t flm_scrub_prof; }; struct flow_template_table { struct flow_pattern_template **pattern_templates; uint8_t nb_pattern_templates; struct flow_actions_template **actions_templates; uint8_t nb_actions_templates; struct flow_template_table_cell *pattern_action_pairs; struct rte_flow_attr attr; uint16_t forced_vlan_vid; uint16_t caller_id; }; void km_attach_ndev_resource_management(struct km_flow_def_s *km, void **handle); void km_free_ndev_resource_management(void **handle); int km_add_match_elem(struct km_flow_def_s *km, uint32_t e_word[4], uint32_t e_mask[4], uint32_t word_len, enum frame_offs_e start, int8_t offset); int km_key_create(struct km_flow_def_s *km, uint32_t port_id); /* * Compares 2 KM key definitions after first collect validate and optimization. * km is compared against an existing km1. * if identical, km1 flow_type is returned */ int km_key_compare(struct km_flow_def_s *km, struct km_flow_def_s *km1); int km_rcp_set(struct km_flow_def_s *km, int index); int km_write_data_match_entry(struct km_flow_def_s *km, uint32_t color); int km_clear_data_match_entry(struct km_flow_def_s *km); void kcc_free_ndev_resource_management(void **handle); /* * Group management */ int flow_group_handle_create(void **handle, uint32_t group_count); int flow_group_handle_destroy(void **handle); int flow_group_translate_get(void *handle, uint8_t owner_id, uint8_t port_id, uint32_t group_in, uint32_t *group_out); #endif /* _FLOW_API_ENGINE_H_ */