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_FDB_MISS, 39 MLXSW_AFK_ELEMENT_L4_PORT_RANGE, 40 MLXSW_AFK_ELEMENT_MAX, 41 }; 42 43 enum mlxsw_afk_element_type { 44 MLXSW_AFK_ELEMENT_TYPE_U32, 45 MLXSW_AFK_ELEMENT_TYPE_BUF, 46 }; 47 48 struct mlxsw_afk_element_info { 49 enum mlxsw_afk_element element; /* element ID */ 50 enum mlxsw_afk_element_type type; 51 struct mlxsw_item item; /* element geometry in internal storage */ 52 }; 53 54 #define MLXSW_AFK_ELEMENT_INFO(_type, _element, _offset, _shift, _size) \ 55 [MLXSW_AFK_ELEMENT_##_element] = { \ 56 .element = MLXSW_AFK_ELEMENT_##_element, \ 57 .type = _type, \ 58 .item = { \ 59 .offset = _offset, \ 60 .shift = _shift, \ 61 .size = {.bits = _size}, \ 62 .name = #_element, \ 63 }, \ 64 } 65 66 #define MLXSW_AFK_ELEMENT_INFO_U32(_element, _offset, _shift, _size) \ 67 MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_U32, \ 68 _element, _offset, _shift, _size) 69 70 #define MLXSW_AFK_ELEMENT_INFO_BUF(_element, _offset, _size) \ 71 MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_BUF, \ 72 _element, _offset, 0, _size) 73 74 #define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x44 75 76 struct mlxsw_afk_element_inst { /* element instance in actual block */ 77 enum mlxsw_afk_element element; 78 enum mlxsw_afk_element_type type; 79 struct mlxsw_item item; /* element geometry in block */ 80 int u32_key_diff; /* in case value needs to be adjusted before write 81 * this diff is here to handle that 82 */ 83 bool avoid_size_check; 84 }; 85 86 #define MLXSW_AFK_ELEMENT_INST(_type, _element, _offset, \ 87 _shift, _size, _u32_key_diff, _avoid_size_check) \ 88 { \ 89 .element = MLXSW_AFK_ELEMENT_##_element, \ 90 .type = _type, \ 91 .item = { \ 92 .offset = _offset, \ 93 .shift = _shift, \ 94 .size = {.bits = _size}, \ 95 .name = #_element, \ 96 }, \ 97 .u32_key_diff = _u32_key_diff, \ 98 .avoid_size_check = _avoid_size_check, \ 99 } 100 101 #define MLXSW_AFK_ELEMENT_INST_U32(_element, _offset, _shift, _size) \ 102 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32, \ 103 _element, _offset, _shift, _size, 0, false) 104 105 #define MLXSW_AFK_ELEMENT_INST_EXT_U32(_element, _offset, \ 106 _shift, _size, _key_diff, \ 107 _avoid_size_check) \ 108 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32, \ 109 _element, _offset, _shift, _size, \ 110 _key_diff, _avoid_size_check) 111 112 #define MLXSW_AFK_ELEMENT_INST_BUF(_element, _offset, _size) \ 113 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_BUF, \ 114 _element, _offset, 0, _size, 0, false) 115 116 struct mlxsw_afk_block { 117 u16 encoding; /* block ID */ 118 struct mlxsw_afk_element_inst *instances; 119 unsigned int instances_count; 120 }; 121 122 #define MLXSW_AFK_BLOCK(_encoding, _instances) \ 123 { \ 124 .encoding = _encoding, \ 125 .instances = _instances, \ 126 .instances_count = ARRAY_SIZE(_instances), \ 127 } 128 129 struct mlxsw_afk_element_usage { 130 DECLARE_BITMAP(usage, MLXSW_AFK_ELEMENT_MAX); 131 }; 132 133 #define mlxsw_afk_element_usage_for_each(element, elusage) \ 134 for_each_set_bit(element, (elusage)->usage, MLXSW_AFK_ELEMENT_MAX) 135 136 static inline void 137 mlxsw_afk_element_usage_add(struct mlxsw_afk_element_usage *elusage, 138 enum mlxsw_afk_element element) 139 { 140 __set_bit(element, elusage->usage); 141 } 142 143 static inline void 144 mlxsw_afk_element_usage_zero(struct mlxsw_afk_element_usage *elusage) 145 { 146 bitmap_zero(elusage->usage, MLXSW_AFK_ELEMENT_MAX); 147 } 148 149 static inline void 150 mlxsw_afk_element_usage_fill(struct mlxsw_afk_element_usage *elusage, 151 const enum mlxsw_afk_element *elements, 152 unsigned int elements_count) 153 { 154 int i; 155 156 mlxsw_afk_element_usage_zero(elusage); 157 for (i = 0; i < elements_count; i++) 158 mlxsw_afk_element_usage_add(elusage, elements[i]); 159 } 160 161 static inline bool 162 mlxsw_afk_element_usage_subset(struct mlxsw_afk_element_usage *elusage_small, 163 struct mlxsw_afk_element_usage *elusage_big) 164 { 165 int i; 166 167 for (i = 0; i < MLXSW_AFK_ELEMENT_MAX; i++) 168 if (test_bit(i, elusage_small->usage) && 169 !test_bit(i, elusage_big->usage)) 170 return false; 171 return true; 172 } 173 174 struct mlxsw_afk; 175 176 struct mlxsw_afk_ops { 177 const struct mlxsw_afk_block *blocks; 178 unsigned int blocks_count; 179 void (*encode_block)(char *output, int block_index, char *block); 180 void (*clear_block)(char *output, int block_index); 181 }; 182 183 struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks, 184 const struct mlxsw_afk_ops *ops); 185 void mlxsw_afk_destroy(struct mlxsw_afk *mlxsw_afk); 186 187 struct mlxsw_afk_key_info; 188 189 struct mlxsw_afk_key_info * 190 mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk, 191 struct mlxsw_afk_element_usage *elusage); 192 void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info); 193 bool mlxsw_afk_key_info_subset(struct mlxsw_afk_key_info *key_info, 194 struct mlxsw_afk_element_usage *elusage); 195 196 u16 197 mlxsw_afk_key_info_block_encoding_get(const struct mlxsw_afk_key_info *key_info, 198 int block_index); 199 unsigned int 200 mlxsw_afk_key_info_blocks_count_get(const struct mlxsw_afk_key_info *key_info); 201 202 struct mlxsw_afk_element_values { 203 struct mlxsw_afk_element_usage elusage; 204 struct { 205 char key[MLXSW_AFK_ELEMENT_STORAGE_SIZE]; 206 char mask[MLXSW_AFK_ELEMENT_STORAGE_SIZE]; 207 } storage; 208 }; 209 210 void mlxsw_afk_values_add_u32(struct mlxsw_afk_element_values *values, 211 enum mlxsw_afk_element element, 212 u32 key_value, u32 mask_value); 213 void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values, 214 enum mlxsw_afk_element element, 215 const char *key_value, const char *mask_value, 216 unsigned int len); 217 void mlxsw_afk_encode(struct mlxsw_afk *mlxsw_afk, 218 struct mlxsw_afk_key_info *key_info, 219 struct mlxsw_afk_element_values *values, 220 char *key, char *mask); 221 void mlxsw_afk_clear(struct mlxsw_afk *mlxsw_afk, char *key, 222 int block_start, int block_end); 223 224 #endif 225