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