GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / net / ethernet / mellanox / mlxsw / core_acl_flex_keys.h
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