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