]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
[karo-tx-linux.git] / drivers / net / ethernet / mellanox / mlxsw / core_acl_flex_keys.h
1 /*
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>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
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.
17  *
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.
21  *
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.
33  */
34
35 #ifndef _MLXSW_CORE_ACL_FLEX_KEYS_H
36 #define _MLXSW_CORE_ACL_FLEX_KEYS_H
37
38 #include <linux/types.h>
39 #include <linux/bitmap.h>
40
41 #include "item.h"
42
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,
60 };
61
62 enum mlxsw_afk_element_type {
63         MLXSW_AFK_ELEMENT_TYPE_U32,
64         MLXSW_AFK_ELEMENT_TYPE_BUF,
65 };
66
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 */
71 };
72
73 #define MLXSW_AFK_ELEMENT_INFO(_type, _element, _offset, _shift, _size)         \
74         [MLXSW_AFK_ELEMENT_##_element] = {                                      \
75                 .element = MLXSW_AFK_ELEMENT_##_element,                        \
76                 .type = _type,                                                  \
77                 .item = {                                                       \
78                         .offset = _offset,                                      \
79                         .shift = _shift,                                        \
80                         .size = {.bits = _size},                                \
81                         .name = #_element,                                      \
82                 },                                                              \
83         }
84
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)
88
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)
92
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.
96  */
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),
113 };
114
115 #define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x38
116
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 */
121 };
122
123 #define MLXSW_AFK_ELEMENT_INST(_type, _element, _offset, _shift, _size)         \
124         {                                                                       \
125                 .info = &mlxsw_afk_element_infos[MLXSW_AFK_ELEMENT_##_element], \
126                 .type = _type,                                                  \
127                 .item = {                                                       \
128                         .offset = _offset,                                      \
129                         .shift = _shift,                                        \
130                         .size = {.bits = _size},                                \
131                         .name = #_element,                                      \
132                 },                                                              \
133         }
134
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)
138
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)
142
143 struct mlxsw_afk_block {
144         u16 encoding; /* block ID */
145         struct mlxsw_afk_element_inst *instances;
146         unsigned int instances_count;
147 };
148
149 #define MLXSW_AFK_BLOCK(_encoding, _instances)                                  \
150         {                                                                       \
151                 .encoding = _encoding,                                          \
152                 .instances = _instances,                                        \
153                 .instances_count = ARRAY_SIZE(_instances),                      \
154         }
155
156 struct mlxsw_afk_element_usage {
157         DECLARE_BITMAP(usage, MLXSW_AFK_ELEMENT_MAX);
158 };
159
160 #define mlxsw_afk_element_usage_for_each(element, elusage)                      \
161         for_each_set_bit(element, (elusage)->usage, MLXSW_AFK_ELEMENT_MAX)
162
163 static inline void
164 mlxsw_afk_element_usage_add(struct mlxsw_afk_element_usage *elusage,
165                             enum mlxsw_afk_element element)
166 {
167         __set_bit(element, elusage->usage);
168 }
169
170 static inline void
171 mlxsw_afk_element_usage_zero(struct mlxsw_afk_element_usage *elusage)
172 {
173         bitmap_zero(elusage->usage, MLXSW_AFK_ELEMENT_MAX);
174 }
175
176 static inline void
177 mlxsw_afk_element_usage_fill(struct mlxsw_afk_element_usage *elusage,
178                              const enum mlxsw_afk_element *elements,
179                              unsigned int elements_count)
180 {
181         int i;
182
183         mlxsw_afk_element_usage_zero(elusage);
184         for (i = 0; i < elements_count; i++)
185                 mlxsw_afk_element_usage_add(elusage, elements[i]);
186 }
187
188 static inline bool
189 mlxsw_afk_element_usage_subset(struct mlxsw_afk_element_usage *elusage_small,
190                                struct mlxsw_afk_element_usage *elusage_big)
191 {
192         int i;
193
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))
197                         return false;
198         return true;
199 }
200
201 struct mlxsw_afk;
202
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);
207
208 struct mlxsw_afk_key_info;
209
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);
216
217 u16
218 mlxsw_afk_key_info_block_encoding_get(const struct mlxsw_afk_key_info *key_info,
219                                       int block_index);
220 unsigned int
221 mlxsw_afk_key_info_blocks_count_get(const struct mlxsw_afk_key_info *key_info);
222
223 struct mlxsw_afk_element_values {
224         struct mlxsw_afk_element_usage elusage;
225         struct {
226                 char key[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
227                 char mask[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
228         } storage;
229 };
230
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,
237                               unsigned int len);
238 void mlxsw_afk_encode(struct mlxsw_afk_key_info *key_info,
239                       struct mlxsw_afk_element_values *values,
240                       char *key, char *mask);
241
242 #endif