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_8_10, 37 MLXSW_AFK_ELEMENT_VIRT_ROUTER_0_7, 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 /* For the purpose of the driver, define an internal storage scratchpad 73 * that will be used to store key/mask values. For each defined element type 74 * define an internal storage geometry. 75 */ 76 static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = { 77 MLXSW_AFK_ELEMENT_INFO_U32(SRC_SYS_PORT, 0x00, 16, 8), 78 MLXSW_AFK_ELEMENT_INFO_BUF(DMAC_32_47, 0x04, 2), 79 MLXSW_AFK_ELEMENT_INFO_BUF(DMAC_0_31, 0x06, 4), 80 MLXSW_AFK_ELEMENT_INFO_BUF(SMAC_32_47, 0x0A, 2), 81 MLXSW_AFK_ELEMENT_INFO_BUF(SMAC_0_31, 0x0C, 4), 82 MLXSW_AFK_ELEMENT_INFO_U32(ETHERTYPE, 0x00, 0, 16), 83 MLXSW_AFK_ELEMENT_INFO_U32(IP_PROTO, 0x10, 0, 8), 84 MLXSW_AFK_ELEMENT_INFO_U32(VID, 0x10, 8, 12), 85 MLXSW_AFK_ELEMENT_INFO_U32(PCP, 0x10, 20, 3), 86 MLXSW_AFK_ELEMENT_INFO_U32(TCP_FLAGS, 0x10, 23, 9), 87 MLXSW_AFK_ELEMENT_INFO_U32(DST_L4_PORT, 0x14, 0, 16), 88 MLXSW_AFK_ELEMENT_INFO_U32(SRC_L4_PORT, 0x14, 16, 16), 89 MLXSW_AFK_ELEMENT_INFO_U32(IP_TTL_, 0x18, 0, 8), 90 MLXSW_AFK_ELEMENT_INFO_U32(IP_ECN, 0x18, 9, 2), 91 MLXSW_AFK_ELEMENT_INFO_U32(IP_DSCP, 0x18, 11, 6), 92 MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_8_10, 0x18, 17, 3), 93 MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_0_7, 0x18, 20, 8), 94 MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_96_127, 0x20, 4), 95 MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_64_95, 0x24, 4), 96 MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_32_63, 0x28, 4), 97 MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_0_31, 0x2C, 4), 98 MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_96_127, 0x30, 4), 99 MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_64_95, 0x34, 4), 100 MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_32_63, 0x38, 4), 101 MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_0_31, 0x3C, 4), 102 }; 103 104 #define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x40 105 106 struct mlxsw_afk_element_inst { /* element instance in actual block */ 107 const struct mlxsw_afk_element_info *info; 108 enum mlxsw_afk_element_type type; 109 struct mlxsw_item item; /* element geometry in block */ 110 }; 111 112 #define MLXSW_AFK_ELEMENT_INST(_type, _element, _offset, _shift, _size) \ 113 { \ 114 .info = &mlxsw_afk_element_infos[MLXSW_AFK_ELEMENT_##_element], \ 115 .type = _type, \ 116 .item = { \ 117 .offset = _offset, \ 118 .shift = _shift, \ 119 .size = {.bits = _size}, \ 120 .name = #_element, \ 121 }, \ 122 } 123 124 #define MLXSW_AFK_ELEMENT_INST_U32(_element, _offset, _shift, _size) \ 125 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32, \ 126 _element, _offset, _shift, _size) 127 128 #define MLXSW_AFK_ELEMENT_INST_BUF(_element, _offset, _size) \ 129 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_BUF, \ 130 _element, _offset, 0, _size) 131 132 struct mlxsw_afk_block { 133 u16 encoding; /* block ID */ 134 struct mlxsw_afk_element_inst *instances; 135 unsigned int instances_count; 136 }; 137 138 #define MLXSW_AFK_BLOCK(_encoding, _instances) \ 139 { \ 140 .encoding = _encoding, \ 141 .instances = _instances, \ 142 .instances_count = ARRAY_SIZE(_instances), \ 143 } 144 145 struct mlxsw_afk_element_usage { 146 DECLARE_BITMAP(usage, MLXSW_AFK_ELEMENT_MAX); 147 }; 148 149 #define mlxsw_afk_element_usage_for_each(element, elusage) \ 150 for_each_set_bit(element, (elusage)->usage, MLXSW_AFK_ELEMENT_MAX) 151 152 static inline void 153 mlxsw_afk_element_usage_add(struct mlxsw_afk_element_usage *elusage, 154 enum mlxsw_afk_element element) 155 { 156 __set_bit(element, elusage->usage); 157 } 158 159 static inline void 160 mlxsw_afk_element_usage_zero(struct mlxsw_afk_element_usage *elusage) 161 { 162 bitmap_zero(elusage->usage, MLXSW_AFK_ELEMENT_MAX); 163 } 164 165 static inline void 166 mlxsw_afk_element_usage_fill(struct mlxsw_afk_element_usage *elusage, 167 const enum mlxsw_afk_element *elements, 168 unsigned int elements_count) 169 { 170 int i; 171 172 mlxsw_afk_element_usage_zero(elusage); 173 for (i = 0; i < elements_count; i++) 174 mlxsw_afk_element_usage_add(elusage, elements[i]); 175 } 176 177 static inline bool 178 mlxsw_afk_element_usage_subset(struct mlxsw_afk_element_usage *elusage_small, 179 struct mlxsw_afk_element_usage *elusage_big) 180 { 181 int i; 182 183 for (i = 0; i < MLXSW_AFK_ELEMENT_MAX; i++) 184 if (test_bit(i, elusage_small->usage) && 185 !test_bit(i, elusage_big->usage)) 186 return false; 187 return true; 188 } 189 190 struct mlxsw_afk; 191 192 struct mlxsw_afk_ops { 193 const struct mlxsw_afk_block *blocks; 194 unsigned int blocks_count; 195 void (*encode_block)(char *output, int block_index, char *block); 196 void (*clear_block)(char *output, int block_index); 197 }; 198 199 struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks, 200 const struct mlxsw_afk_ops *ops); 201 void mlxsw_afk_destroy(struct mlxsw_afk *mlxsw_afk); 202 203 struct mlxsw_afk_key_info; 204 205 struct mlxsw_afk_key_info * 206 mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk, 207 struct mlxsw_afk_element_usage *elusage); 208 void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info); 209 bool mlxsw_afk_key_info_subset(struct mlxsw_afk_key_info *key_info, 210 struct mlxsw_afk_element_usage *elusage); 211 212 u16 213 mlxsw_afk_key_info_block_encoding_get(const struct mlxsw_afk_key_info *key_info, 214 int block_index); 215 unsigned int 216 mlxsw_afk_key_info_blocks_count_get(const struct mlxsw_afk_key_info *key_info); 217 218 struct mlxsw_afk_element_values { 219 struct mlxsw_afk_element_usage elusage; 220 struct { 221 char key[MLXSW_AFK_ELEMENT_STORAGE_SIZE]; 222 char mask[MLXSW_AFK_ELEMENT_STORAGE_SIZE]; 223 } storage; 224 }; 225 226 void mlxsw_afk_values_add_u32(struct mlxsw_afk_element_values *values, 227 enum mlxsw_afk_element element, 228 u32 key_value, u32 mask_value); 229 void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values, 230 enum mlxsw_afk_element element, 231 const char *key_value, const char *mask_value, 232 unsigned int len); 233 void mlxsw_afk_encode(struct mlxsw_afk *mlxsw_afk, 234 struct mlxsw_afk_key_info *key_info, 235 struct mlxsw_afk_element_values *values, 236 char *key, char *mask); 237 void mlxsw_afk_clear(struct mlxsw_afk *mlxsw_afk, char *key, 238 int block_start, int block_end); 239 240 #endif 241