2 * drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h
3 * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2017 Jiri Pirko <jiri@mellanox.com>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the names of the copyright holders nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * Alternatively, this software may be distributed under the terms of the
19 * GNU General Public License ("GPL") version 2 as published by the Free
20 * Software Foundation.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
35 #ifndef _MLXSW_CORE_ACL_FLEX_KEYS_H
36 #define _MLXSW_CORE_ACL_FLEX_KEYS_H
38 #include <linux/types.h>
39 #include <linux/bitmap.h>
43 enum mlxsw_afk_element {
44 MLXSW_AFK_ELEMENT_SRC_SYS_PORT,
45 MLXSW_AFK_ELEMENT_DMAC,
46 MLXSW_AFK_ELEMENT_SMAC,
47 MLXSW_AFK_ELEMENT_ETHERTYPE,
48 MLXSW_AFK_ELEMENT_IP_PROTO,
49 MLXSW_AFK_ELEMENT_SRC_IP4,
50 MLXSW_AFK_ELEMENT_DST_IP4,
51 MLXSW_AFK_ELEMENT_SRC_IP6_HI,
52 MLXSW_AFK_ELEMENT_SRC_IP6_LO,
53 MLXSW_AFK_ELEMENT_DST_IP6_HI,
54 MLXSW_AFK_ELEMENT_DST_IP6_LO,
55 MLXSW_AFK_ELEMENT_DST_L4_PORT,
56 MLXSW_AFK_ELEMENT_SRC_L4_PORT,
57 MLXSW_AFK_ELEMENT_VID,
58 MLXSW_AFK_ELEMENT_PCP,
59 MLXSW_AFK_ELEMENT_MAX,
62 enum mlxsw_afk_element_type {
63 MLXSW_AFK_ELEMENT_TYPE_U32,
64 MLXSW_AFK_ELEMENT_TYPE_BUF,
67 struct mlxsw_afk_element_info {
68 enum mlxsw_afk_element element; /* element ID */
69 enum mlxsw_afk_element_type type;
70 struct mlxsw_item item; /* element geometry in internal storage */
73 #define MLXSW_AFK_ELEMENT_INFO(_type, _element, _offset, _shift, _size) \
74 [MLXSW_AFK_ELEMENT_##_element] = { \
75 .element = MLXSW_AFK_ELEMENT_##_element, \
80 .size = {.bits = _size}, \
85 #define MLXSW_AFK_ELEMENT_INFO_U32(_element, _offset, _shift, _size) \
86 MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_U32, \
87 _element, _offset, _shift, _size)
89 #define MLXSW_AFK_ELEMENT_INFO_BUF(_element, _offset, _size) \
90 MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_BUF, \
91 _element, _offset, 0, _size)
93 /* For the purpose of the driver, define an internal storage scratchpad
94 * that will be used to store key/mask values. For each defined element type
95 * define an internal storage geometry.
97 static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = {
98 MLXSW_AFK_ELEMENT_INFO_U32(SRC_SYS_PORT, 0x00, 16, 16),
99 MLXSW_AFK_ELEMENT_INFO_BUF(DMAC, 0x04, 6),
100 MLXSW_AFK_ELEMENT_INFO_BUF(SMAC, 0x0A, 6),
101 MLXSW_AFK_ELEMENT_INFO_U32(ETHERTYPE, 0x00, 0, 16),
102 MLXSW_AFK_ELEMENT_INFO_U32(IP_PROTO, 0x10, 0, 8),
103 MLXSW_AFK_ELEMENT_INFO_U32(VID, 0x10, 8, 12),
104 MLXSW_AFK_ELEMENT_INFO_U32(PCP, 0x10, 20, 3),
105 MLXSW_AFK_ELEMENT_INFO_U32(SRC_IP4, 0x18, 0, 32),
106 MLXSW_AFK_ELEMENT_INFO_U32(DST_IP4, 0x1C, 0, 32),
107 MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP6_HI, 0x18, 8),
108 MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP6_LO, 0x20, 8),
109 MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP6_HI, 0x28, 8),
110 MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP6_LO, 0x30, 8),
111 MLXSW_AFK_ELEMENT_INFO_U32(DST_L4_PORT, 0x14, 0, 16),
112 MLXSW_AFK_ELEMENT_INFO_U32(SRC_L4_PORT, 0x14, 16, 16),
115 #define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x38
117 struct mlxsw_afk_element_inst { /* element instance in actual block */
118 const struct mlxsw_afk_element_info *info;
119 enum mlxsw_afk_element_type type;
120 struct mlxsw_item item; /* element geometry in block */
123 #define MLXSW_AFK_ELEMENT_INST(_type, _element, _offset, _shift, _size) \
125 .info = &mlxsw_afk_element_infos[MLXSW_AFK_ELEMENT_##_element], \
130 .size = {.bits = _size}, \
135 #define MLXSW_AFK_ELEMENT_INST_U32(_element, _offset, _shift, _size) \
136 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32, \
137 _element, _offset, _shift, _size)
139 #define MLXSW_AFK_ELEMENT_INST_BUF(_element, _offset, _size) \
140 MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_BUF, \
141 _element, _offset, 0, _size)
143 struct mlxsw_afk_block {
144 u16 encoding; /* block ID */
145 struct mlxsw_afk_element_inst *instances;
146 unsigned int instances_count;
149 #define MLXSW_AFK_BLOCK(_encoding, _instances) \
151 .encoding = _encoding, \
152 .instances = _instances, \
153 .instances_count = ARRAY_SIZE(_instances), \
156 struct mlxsw_afk_element_usage {
157 DECLARE_BITMAP(usage, MLXSW_AFK_ELEMENT_MAX);
160 #define mlxsw_afk_element_usage_for_each(element, elusage) \
161 for_each_set_bit(element, (elusage)->usage, MLXSW_AFK_ELEMENT_MAX)
164 mlxsw_afk_element_usage_add(struct mlxsw_afk_element_usage *elusage,
165 enum mlxsw_afk_element element)
167 __set_bit(element, elusage->usage);
171 mlxsw_afk_element_usage_zero(struct mlxsw_afk_element_usage *elusage)
173 bitmap_zero(elusage->usage, MLXSW_AFK_ELEMENT_MAX);
177 mlxsw_afk_element_usage_fill(struct mlxsw_afk_element_usage *elusage,
178 const enum mlxsw_afk_element *elements,
179 unsigned int elements_count)
183 mlxsw_afk_element_usage_zero(elusage);
184 for (i = 0; i < elements_count; i++)
185 mlxsw_afk_element_usage_add(elusage, elements[i]);
189 mlxsw_afk_element_usage_subset(struct mlxsw_afk_element_usage *elusage_small,
190 struct mlxsw_afk_element_usage *elusage_big)
194 for (i = 0; i < MLXSW_AFK_ELEMENT_MAX; i++)
195 if (test_bit(i, elusage_small->usage) &&
196 !test_bit(i, elusage_big->usage))
203 struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
204 const struct mlxsw_afk_block *blocks,
205 unsigned int blocks_count);
206 void mlxsw_afk_destroy(struct mlxsw_afk *mlxsw_afk);
208 struct mlxsw_afk_key_info;
210 struct mlxsw_afk_key_info *
211 mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk,
212 struct mlxsw_afk_element_usage *elusage);
213 void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info);
214 bool mlxsw_afk_key_info_subset(struct mlxsw_afk_key_info *key_info,
215 struct mlxsw_afk_element_usage *elusage);
218 mlxsw_afk_key_info_block_encoding_get(const struct mlxsw_afk_key_info *key_info,
221 mlxsw_afk_key_info_blocks_count_get(const struct mlxsw_afk_key_info *key_info);
223 struct mlxsw_afk_element_values {
224 struct mlxsw_afk_element_usage elusage;
226 char key[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
227 char mask[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
231 void mlxsw_afk_values_add_u32(struct mlxsw_afk_element_values *values,
232 enum mlxsw_afk_element element,
233 u32 key_value, u32 mask_value);
234 void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values,
235 enum mlxsw_afk_element element,
236 const char *key_value, const char *mask_value,
238 void mlxsw_afk_encode(struct mlxsw_afk_key_info *key_info,
239 struct mlxsw_afk_element_values *values,
240 char *key, char *mask);