/* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2001-2023 Intel Corporation */ #ifndef _CPFL_RULES_API_H_ #define _CPFL_RULES_API_H_ #include #include "cpfl_actions.h" #include "cpfl_controlq.h" /* Common Bit Mask Macros */ #define CPFL_BIT(b) (1 << (b)) #define MAKE_MASK(type, mask, shift) ((u##type) (mask) << (shift)) #define SHIFT_VAL_LT(type, val, field) \ (((u##type)(val) << field##_S) & field##_M) #define SHIFT_VAL_RT(type, val, field) \ (((u##type)(val) & field##_M) >> field##_S) #define MAKE_MASK_VAL(type, bit_len) (((u##type)0x01 << (bit_len)) - 1) #define MAKE_MASK_VAL16(bit_len) MAKE_MASK_VAL(16, bit_len) #define MAKE_MASK_VAL64(bit_len) MAKE_MASK_VAL(64, bit_len) #define MAKE_MASK64(mask, shift) MAKE_MASK(64, mask, shift) #define MAKE_MASK16(mask, shift) MAKE_MASK(16, mask, shift) #define MAKE_MASK32(mask, shift) MAKE_MASK(32, mask, shift) /* Make masks with bit length and left-shifting count */ #define MAKE_SMASK(type, bits, shift) \ ((((u##type)1 << (bits)) - 1) << (shift)) #define MAKE_SMASK64(bits, shift) MAKE_SMASK(64, bits, shift) #define MAKE_SMASK32(bits, shift) MAKE_SMASK(32, bits, shift) #define MAKE_SMASK16(bits, shift) MAKE_SMASK(16, bits, shift) #define SHIFT_VAL64(val, field) SHIFT_VAL_LT(64, val, field) #define SHIFT_VAL32(val, field) SHIFT_VAL_LT(32, val, field) #define SHIFT_VAL16(val, field) SHIFT_VAL_LT(16, val, field) /* Rule Config queue opcodes */ enum cpfl_ctlq_rule_cfg_opc { cpfl_ctlq_sem_add_rule = 0x1303, cpfl_ctlq_sem_update_rule = 0x1304, cpfl_ctlq_sem_del_rule = 0x1305, cpfl_ctlq_sem_query_rule = 0x1306, cpfl_ctlq_sem_query_rule_hash_addr = 0x1307, cpfl_ctlq_sem_query_del_rule_hash_addr = 0x1308, cpfl_ctlq_mod_add_update_rule = 0x1360, cpfl_ctlq_mod_query_rule = 0x1361, }; enum cpfl_cfg_pkt_error_code { CPFL_CFG_PKT_ERR_OK = 0, CPFL_CFG_PKT_ERR_ESRCH = 1, /* Bad opcode */ CPFL_CFG_PKT_ERR_EEXIST = 2, /* Entry Already exists */ CPFL_CFG_PKT_ERR_ENOSPC = 4, /* No space left in the table*/ CPFL_CFG_PKT_ERR_ERANGE = 5, /* Parameter out of range */ CPFL_CFG_PKT_ERR_ESBCOMP = 6, /* Completion Error */ CPFL_CFG_PKT_ERR_ENOPIN = 7, /* Entry cannot be pinned in cache */ CPFL_CFG_PKT_ERR_ENOTFND = 8, /* Entry Not exists */ CPFL_CFG_PKT_ERR_EMAXCOL = 9 /* Max Hash Collision */ }; static const char * const cpfl_cfg_pkt_errormsg[] = { [CPFL_CFG_PKT_ERR_ESRCH] = "Bad opcode", [CPFL_CFG_PKT_ERR_EEXIST] = "The rule conflicts with already existed one", [CPFL_CFG_PKT_ERR_ENOSPC] = "No space left in the table", [CPFL_CFG_PKT_ERR_ERANGE] = "Parameter out of range", [CPFL_CFG_PKT_ERR_ESBCOMP] = "Completion error", [CPFL_CFG_PKT_ERR_ENOPIN] = "Entry cannot be pinned in cache", [CPFL_CFG_PKT_ERR_ENOTFND] = "Entry does not exist", [CPFL_CFG_PKT_ERR_EMAXCOL] = "Maximum Hash Collisions reached", }; /* macros for creating context for rule descriptor */ #define MEV_RULE_VSI_ID_S 0 #define MEV_RULE_VSI_ID_M \ MAKE_MASK64(0x7FF, MEV_RULE_VSI_ID_S) #define MEV_RULE_TIME_SEL_S 13 #define MEV_RULE_TIME_SEL_M \ MAKE_MASK64(0x3, MEV_RULE_TIME_SEL_S) #define MEV_RULE_TIME_SEL_VAL_S 15 #define MEV_RULE_TIME_SEL_VAL_M \ MAKE_MASK64(0x1, MEV_RULE_TIME_SEL_VAL_S) #define MEV_RULE_PORT_NUM_S 16 #define MEV_RULE_HOST_ID_S 18 #define MEV_RULE_PORT_NUM_M \ MAKE_MASK64(0x3, MEV_RULE_PORT_NUM_S) #define MEV_RULE_HOST_ID_M \ MAKE_MASK64(0x7, MEV_RULE_HOST_ID_S) #define MEV_RULE_CACHE_WR_THRU_S 21 #define MEV_RULE_CACHE_WR_THRU_M \ MAKE_MASK64(0x1, MEV_RULE_CACHE_WR_THRU_S) #define MEV_RULE_RESP_REQ_S 22 #define MEV_RULE_RESP_REQ_M \ MAKE_MASK64(0x3, MEV_RULE_RESP_REQ_S) #define MEV_RULE_OBJ_ADDR_S 24 #define MEV_RULE_OBJ_ADDR_M \ MAKE_MASK64(0x7FFFFFF, MEV_RULE_OBJ_ADDR_S) #define MEV_RULE_OBJ_ID_S 59 #define MEV_RULE_OBJ_ID_M \ MAKE_MASK64((uint64_t)0x3, MEV_RULE_OBJ_ID_S) /* macros for creating CFG_CTRL for sem/lem rule blob */ #define MEV_RULE_CFG_CTRL_PROF_ID_S 0 #define MEV_RULE_CFG_CTRL_PROF_ID_M \ MAKE_MASK16(0x7FF, MEV_RULE_CFG_CTRL_PROF_ID_S) #define MEV_RULE_CFG_CTRL_SUB_PROF_ID_S 11 #define MEV_RULE_CFG_CTRL_SUB_PROF_ID_M \ MAKE_MASK16(0x3, MEV_RULE_CFG_CTRL_SUB_PROF_ID_S) #define MEV_RULE_CFG_CTRL_PIN_CACHE_S 13 #define MEV_RULE_CFG_CTRL_PIN_CACHE_M \ MAKE_MASK16(0x1, MEV_RULE_CFG_CTRL_PIN_CACHE_S) #define MEV_RULE_CFG_CTRL_CLEAR_MIRROR_S 14 #define MEV_RULE_CFG_CTRL_CLEAR_MIRROR_M \ MAKE_MASK16(0x1, MEV_RULE_CFG_CTRL_CLEAR_MIRROR_S) #define MEV_RULE_CFG_CTRL_FIXED_FETCH_S 15 #define MEV_RULE_CFG_CTRL_FIXED_FETCH_M \ MAKE_MASK16(0x1, MEV_RULE_CFG_CTRL_FIXED_FETCH_S) /** * macro to build the CFG_CTRL for rule packet data, which is one of * cpfl_prep_sem_rule_blob()'s input parameter. */ /* build SEM CFG_CTRL*/ #define CPFL_GET_MEV_SEM_RULE_CFG_CTRL(prof_id, sub_prof_id, \ pin_to_cache, fixed_fetch) \ (SHIFT_VAL16((prof_id), MEV_RULE_CFG_CTRL_PROF_ID) | \ SHIFT_VAL16((sub_prof_id), MEV_RULE_CFG_CTRL_SUB_PROF_ID) | \ SHIFT_VAL16((pin_to_cache), MEV_RULE_CFG_CTRL_PIN_CACHE) | \ SHIFT_VAL16((fixed_fetch), MEV_RULE_CFG_CTRL_FIXED_FETCH)) /* build LEM CFG_CTRL*/ #define CPFL_GET_MEV_LEM_RULE_CFG_CTRL(prof_id, pin_to_cache, clear_mirror) \ (SHIFT_VAL16(prof_id, MEV_RULE_CFG_CTRL_PROF_ID) | \ SHIFT_VAL16(pin_to_cache, MEV_RULE_CFG_CTRL_PIN_CACHE) | \ SHIFT_VAL16(clear_mirror, MEV_RULE_CFG_CTRL_CLEAR_MIRROR)) /* macros for creating mod content config packets */ #define MEV_RULE_MOD_INDEX_S 24 #define MEV_RULE_MOD_INDEX_M \ MAKE_MASK64(0xFFFFFFFF, MEV_RULE_MOD_INDEX_S) #define MEV_RULE_PIN_MOD_CONTENT_S 62 #define MEV_RULE_PIN_MOD_CONTENT_M \ MAKE_MASK64((uint64_t)0x1, MEV_RULE_PIN_MOD_CONTENT_S) #define MEV_RULE_MOD_OBJ_SIZE_S 63 #define MEV_RULE_MOD_OBJ_SIZE_M \ MAKE_MASK64((uint64_t)0x1, MEV_RULE_MOD_OBJ_SIZE_S) /** * struct cpfl_sem_rule_cfg_pkt - Describes rule information for SEM * note: The key may be in mixed big/little endian format, the rest of members * are in little endian */ struct cpfl_sem_rule_cfg_pkt { #define MEV_SEM_RULE_KEY_SIZE 128 uint8_t key[MEV_SEM_RULE_KEY_SIZE]; #define MEV_SEM_RULE_ACT_SIZE 72 uint8_t actions[MEV_SEM_RULE_ACT_SIZE]; /* Bit(s): * 10:0 : PROFILE_ID * 12:11: SUB_PROF_ID (used for SEM only) * 13 : pin the SEM key content into the cache * 14 : Reserved * 15 : Fixed_fetch */ uint8_t cfg_ctrl[2]; /* Bit(s): * 0: valid * 15:1: Hints * 26:16: PROFILE_ID, the profile associated with the entry * 31:27: PF * 55:32: FLOW ID (assigned by HW) * 63:56: EPOCH */ uint8_t ctrl_word[8]; uint8_t padding[46]; }; /** * union cpfl_rule_cfg_pkt_record - Describes rule data blob */ union cpfl_rule_cfg_pkt_record { struct cpfl_sem_rule_cfg_pkt sem_rule; uint8_t pkt_data[256]; uint8_t mod_blob[256]; }; /** * cpfl_rule_query_addr - LEM/SEM Rule Query Address structure */ struct cpfl_rule_query_addr { uint8_t obj_id; uint32_t obj_addr; }; /** * cpfl_rule_query_del_addr - Rule Query and Delete Address */ struct cpfl_rule_query_del_addr { uint8_t obj_id; uint32_t obj_addr; }; /** * cpfl_rule_mod_content - MOD Rule Content */ struct cpfl_rule_mod_content { uint8_t obj_size; uint8_t pin_content; uint32_t index; }; /** * cpfl_rule_cfg_data_common - data struct for all rule opcodes *note: some rules may only require part of structure */ struct cpfl_rule_cfg_data_common { enum cpfl_ctlq_rule_cfg_opc opc; uint64_t cookie; uint16_t vsi_id; uint8_t port_num; uint8_t host_id; uint8_t time_sel; uint8_t time_sel_val; uint8_t cache_wr_thru; uint8_t resp_req; uint32_t ret_val; uint16_t buf_len; struct idpf_dma_mem *payload; }; /** * cpfl_rule_cfg_data - rule config data * note: Before sending rule to HW, caller needs to fill * in this struct then call cpfl_prep_rule_desc(). */ struct cpfl_rule_cfg_data { struct cpfl_rule_cfg_data_common common; union { struct cpfl_rule_query_addr query_addr; struct cpfl_rule_query_del_addr query_del_addr; struct cpfl_rule_mod_content mod_content; } ext; }; /** * cpfl_fill_rule_mod_content - fill info for mod content */ static inline void cpfl_fill_rule_mod_content(uint8_t mod_obj_size, uint8_t pin_mod_content, uint32_t mod_index, struct cpfl_rule_mod_content *mod_content) { mod_content->obj_size = mod_obj_size; mod_content->pin_content = pin_mod_content; mod_content->index = mod_index; } /** * cpfl_fill_rule_cfg_data_common - fill in rule config data for all opcodes * note: call this function before calls cpfl_prep_rule_desc() */ static inline void cpfl_fill_rule_cfg_data_common(enum cpfl_ctlq_rule_cfg_opc opc, uint64_t cookie, uint16_t vsi_id, uint8_t port_num, uint8_t host_id, uint8_t time_sel, uint8_t time_sel_val, uint8_t cache_wr_thru, uint8_t resp_req, uint16_t payload_len, struct idpf_dma_mem *payload, struct cpfl_rule_cfg_data_common *cfg_cmn) { cfg_cmn->opc = opc; cfg_cmn->cookie = cookie; cfg_cmn->vsi_id = vsi_id; cfg_cmn->port_num = port_num; cfg_cmn->resp_req = resp_req; cfg_cmn->ret_val = 0; cfg_cmn->host_id = host_id; cfg_cmn->time_sel = time_sel; cfg_cmn->time_sel_val = time_sel_val; cfg_cmn->cache_wr_thru = cache_wr_thru; cfg_cmn->buf_len = payload_len; cfg_cmn->payload = payload; } void cpfl_prep_rule_desc(struct cpfl_rule_cfg_data *cfg_data, struct idpf_ctlq_msg *ctlq_msg); void cpfl_prep_sem_rule_blob(const uint8_t *key, uint8_t key_byte_len, const uint8_t *act_bytes, uint8_t act_byte_len, uint16_t cfg_ctrl, union cpfl_rule_cfg_pkt_record *rule_blob); #endif /* _CPFL_RULES_API_H_ */