1 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ 2 /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */ 3 4 #ifndef _MLXSW_CORE_ACL_FLEX_KEYS_H 5 #define _MLXSW_CORE_ACL_FLEX_KEYS_H 6 7 #include <linux/types.h> 8 #include <linux/bitmap.h> 9 10 #include "item.h" 11 12 enum mlxsw_afk_element { 13 MLXSW_AFK_ELEMENT_SRC_SYS_PORT, 14 MLXSW_AFK_ELEMENT_DMAC_32_47, 15 MLXSW_AFK_ELEMENT_DMAC_0_31, 16 MLXSW_AFK_ELEMENT_SMAC_32_47, 17 MLXSW_AFK_ELEMENT_SMAC_0_31, 18 MLXSW_AFK_ELEMENT_ETHERTYPE, 19 MLXSW_AFK_ELEMENT_IP_PROTO, 20 MLXSW_AFK_ELEMENT_SRC_IP_96_127, 21 MLXSW_AFK_ELEMENT_SRC_IP_64_95, 22 MLXSW_AFK_ELEMENT_SRC_IP_32_63, 23 MLXSW_AFK_ELEMENT_SRC_IP_0_31, 24 MLXSW_AFK_ELEMENT_DST_IP_96_127, 25 MLXSW_AFK_ELEMENT_DST_IP_64_95, 26 MLXSW_AFK_ELEMENT_DST_IP_32_63, 27 MLXSW_AFK_ELEMENT_DST_IP_0_31, 28 MLXSW_AFK_ELEMENT_DST_L4_PORT, 29 MLXSW_AFK_ELEMENT_SRC_L4_PORT, 30 MLXSW_AFK_ELEMENT_VID, 31 MLXSW_AFK_ELEMENT_PCP, 32 MLXSW_AFK_ELEMENT_TCP_FLAGS, 33 MLXSW_AFK_ELEMENT_IP_TTL_, 34 MLXSW_AFK_ELEMENT_IP_ECN, 35 MLXSW_AFK_ELEMENT_IP_DSCP, 36 MLXSW_AFK_ELEMENT_VIRT_ROUTER_MSB, 37 MLXSW_AFK_ELEMENT_VIRT_ROUTER_LSB, 38 MLXSW_AFK_ELEMENT_MAX, 39 }; 40 41 enum mlxsw_afk_element_type { 42 MLXSW_AFK_ELEMENT_TYPE_U32, 43 MLXSW_AFK_ELEMENT_TYPE_BUF, 44 }; 45 46 struct mlxsw_afk_element_info { 47 enum mlxsw_afk_element element; /* element ID */ 48 enum mlxsw_afk_element_type type; 49 struct mlxsw_item item; /* element geometry in internal storage */ 50 }; 51 52 #define MLXSW_AFK_ELEMENT_INFO(_type, _element, _offset, _shift, _size) \ 53 [MLXSW_AFK_ELEMENT_##_element] = { \ 54 .element = MLXSW_AFK_ELEMENT_##_element, \ 55 .type = _type, \ 56 .item = { \ 57 .offset = _offset, \ 58 .shift = _shift, \ 59 .size = {.bits = _size}, \ 60 .name = #_element, \ 61 }, \ 62 } 63 64 #define MLXSW_AFK_ELEMENT_INFO_U32(_element, _offset, _shift, _size) \ 65 MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_U32, \ 66 _element, _offset, _shift, _size) 67 68 #define MLXSW_AFK_ELEMENT_INFO_BUF(_element, _offset, _size) \ 69 MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_BUF, \ 70 _element, _offset, 0, _size) 71 72 #define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x40 73 74 struct mlxsw_afk_element_inst { /* element instance in actual block */ 75 enum mlxsw_afk_element element; 76 enum mlxsw_afk_element_type type; 77 struct mlxsw_item item; /* element geometry in block */ 78 int u32_key_diff; /* in case value needs to be adjusted before write 79 * this diff is here to handle that 80 */ 81 bool avoid_size_check; 82 }; 83 84 #define MLXSW_AFK_ELEMENT_INST(_type, _element, _offset, \ 85 _shift, _size, _u32_key_diff, _avoid_size_check) \ 86 { \ 87 .element = MLXSW_AFK_ELEMENT_##_element, \ 88 .type = _type, \ 89 .item = { \ 90 .offset = _offset, \ 91 .shift = _shift, \ 92 .size = {.bits = _size}, \ 93 .name = #_element, \ 94 }, \ 95 .u32_key_diff = _u32_key_diff, \ 96 .avoid_size_check = _avoid_size_check, \ 97 } 98 99 #define MLXSW_AFK_ELEMENT_INST_U32(_element, _offset, _shift, _size) \ 100 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32, \ 101 _element, _offset, _shift, _size, 0, false) 102 103 #define MLXSW_AFK_ELEMENT_INST_EXT_U32(_element, _offset, \ 104 _shift, _size, _key_diff, \ 105 _avoid_size_check) \ 106 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32, \ 107 _element, _offset, _shift, _size, \ 108 _key_diff, _avoid_size_check) 109 110 #define MLXSW_AFK_ELEMENT_INST_BUF(_element, _offset, _size) \ 111 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_BUF, \ 112 _element, _offset, 0, _size, 0, false) 113 114 struct mlxsw_afk_block { 115 u16 encoding; /* block ID */ 116 struct mlxsw_afk_element_inst *instances; 117 unsigned int instances_count; 118 }; 119 120 #define MLXSW_AFK_BLOCK(_encoding, _instances) \ 121 { \ 122 .encoding = _encoding, \ 123 .instances = _instances, \ 124 .instances_count = ARRAY_SIZE(_instances), \ 125 } 126 127 struct mlxsw_afk_element_usage { 128 DECLARE_BITMAP(usage, MLXSW_AFK_ELEMENT_MAX); 129 }; 130 131 #define mlxsw_afk_element_usage_for_each(element, elusage) \ 132 for_each_set_bit(element, (elusage)->usage, MLXSW_AFK_ELEMENT_MAX) 133 134 static inline void 135 mlxsw_afk_element_usage_add(struct mlxsw_afk_element_usage *elusage, 136 enum mlxsw_afk_element element) 137 { 138 __set_bit(element, elusage->usage); 139 } 140 141 static inline void 142 mlxsw_afk_element_usage_zero(struct mlxsw_afk_element_usage *elusage) 143 { 144 bitmap_zero(elusage->usage, MLXSW_AFK_ELEMENT_MAX); 145 } 146 147 static inline void 148 mlxsw_afk_element_usage_fill(struct mlxsw_afk_element_usage *elusage, 149 const enum mlxsw_afk_element *elements, 150 unsigned int elements_count) 151 { 152 int i; 153 154 mlxsw_afk_element_usage_zero(elusage); 155 for (i = 0; i < elements_count; i++) 156 mlxsw_afk_element_usage_add(elusage, elements[i]); 157 } 158 159 static inline bool 160 mlxsw_afk_element_usage_subset(struct mlxsw_afk_element_usage *elusage_small, 161 struct mlxsw_afk_element_usage *elusage_big) 162 { 163 int i; 164 165 for (i = 0; i < MLXSW_AFK_ELEMENT_MAX; i++) 166 if (test_bit(i, elusage_small->usage) && 167 !test_bit(i, elusage_big->usage)) 168 return false; 169 return true; 170 } 171 172 struct mlxsw_afk; 173 174 struct mlxsw_afk_ops { 175 const struct mlxsw_afk_block *blocks; 176 unsigned int blocks_count; 177 void (*encode_block)(char *output, int block_index, char *block); 178 void (*clear_block)(char *output, int block_index); 179 }; 180 181 struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks, 182 const struct mlxsw_afk_ops *ops); 183 void mlxsw_afk_destroy(struct mlxsw_afk *mlxsw_afk); 184 185 struct mlxsw_afk_key_info; 186 187 struct mlxsw_afk_key_info * 188 mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk, 189 struct mlxsw_afk_element_usage *elusage); 190 void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info); 191 bool mlxsw_afk_key_info_subset(struct mlxsw_afk_key_info *key_info, 192 struct mlxsw_afk_element_usage *elusage); 193 194 u16 195 mlxsw_afk_key_info_block_encoding_get(const struct mlxsw_afk_key_info *key_info, 196 int block_index); 197 unsigned int 198 mlxsw_afk_key_info_blocks_count_get(const struct mlxsw_afk_key_info *key_info); 199 200 struct mlxsw_afk_element_values { 201 struct mlxsw_afk_element_usage elusage; 202 struct { 203 char key[MLXSW_AFK_ELEMENT_STORAGE_SIZE]; 204 char mask[MLXSW_AFK_ELEMENT_STORAGE_SIZE]; 205 } storage; 206 }; 207 208 void mlxsw_afk_values_add_u32(struct mlxsw_afk_element_values *values, 209 enum mlxsw_afk_element element, 210 u32 key_value, u32 mask_value); 211 void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values, 212 enum mlxsw_afk_element element, 213 const char *key_value, const char *mask_value, 214 unsigned int len); 215 void mlxsw_afk_encode(struct mlxsw_afk *mlxsw_afk, 216 struct mlxsw_afk_key_info *key_info, 217 struct mlxsw_afk_element_values *values, 218 char *key, char *mask); 219 void mlxsw_afk_clear(struct mlxsw_afk *mlxsw_afk, char *key, 220 int block_start, int block_end); 221 222 #endif 223