1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */
4 #include <linux/kernel.h>
5 #include <linux/module.h>
8 #include "core_acl_flex_keys.h"
10 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_dmac
[] = {
11 MLXSW_AFK_ELEMENT_INST_BUF(DMAC_32_47
, 0x00, 2),
12 MLXSW_AFK_ELEMENT_INST_BUF(DMAC_0_31
, 0x02, 4),
13 MLXSW_AFK_ELEMENT_INST_U32(PCP
, 0x08, 13, 3),
14 MLXSW_AFK_ELEMENT_INST_U32(VID
, 0x08, 0, 12),
15 MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT
, 0x0C, 0, 16),
18 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_smac
[] = {
19 MLXSW_AFK_ELEMENT_INST_BUF(SMAC_32_47
, 0x00, 2),
20 MLXSW_AFK_ELEMENT_INST_BUF(SMAC_0_31
, 0x02, 4),
21 MLXSW_AFK_ELEMENT_INST_U32(PCP
, 0x08, 13, 3),
22 MLXSW_AFK_ELEMENT_INST_U32(VID
, 0x08, 0, 12),
23 MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT
, 0x0C, 0, 16),
26 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_smac_ex
[] = {
27 MLXSW_AFK_ELEMENT_INST_BUF(SMAC_32_47
, 0x02, 2),
28 MLXSW_AFK_ELEMENT_INST_BUF(SMAC_0_31
, 0x04, 4),
29 MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE
, 0x0C, 0, 16),
32 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_sip
[] = {
33 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31
, 0x00, 4),
34 MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO
, 0x08, 0, 8),
35 MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT
, 0x0C, 0, 16),
38 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_dip
[] = {
39 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31
, 0x00, 4),
40 MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO
, 0x08, 0, 8),
41 MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT
, 0x0C, 0, 16),
44 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4
[] = {
45 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31
, 0x00, 4),
46 MLXSW_AFK_ELEMENT_INST_U32(IP_ECN
, 0x04, 4, 2),
47 MLXSW_AFK_ELEMENT_INST_U32(IP_TTL_
, 0x04, 24, 8),
48 MLXSW_AFK_ELEMENT_INST_U32(IP_DSCP
, 0x08, 0, 6),
49 MLXSW_AFK_ELEMENT_INST_U32(TCP_FLAGS
, 0x08, 8, 9), /* TCP_CONTROL+TCP_ECN */
52 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_ex
[] = {
53 MLXSW_AFK_ELEMENT_INST_U32(VID
, 0x00, 0, 12),
54 MLXSW_AFK_ELEMENT_INST_U32(PCP
, 0x08, 29, 3),
55 MLXSW_AFK_ELEMENT_INST_U32(SRC_L4_PORT
, 0x08, 0, 16),
56 MLXSW_AFK_ELEMENT_INST_U32(DST_L4_PORT
, 0x0C, 0, 16),
59 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_dip
[] = {
60 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_32_63
, 0x00, 4),
61 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31
, 0x04, 4),
64 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_ex1
[] = {
65 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_96_127
, 0x00, 4),
66 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_64_95
, 0x04, 4),
67 MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO
, 0x08, 0, 8),
70 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_sip
[] = {
71 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_32_63
, 0x00, 4),
72 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31
, 0x04, 4),
75 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_sip_ex
[] = {
76 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_96_127
, 0x00, 4),
77 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_64_95
, 0x04, 4),
80 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_packet_type
[] = {
81 MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE
, 0x00, 0, 16),
84 static const struct mlxsw_afk_block mlxsw_sp1_afk_blocks
[] = {
85 MLXSW_AFK_BLOCK(0x10, mlxsw_sp_afk_element_info_l2_dmac
),
86 MLXSW_AFK_BLOCK(0x11, mlxsw_sp_afk_element_info_l2_smac
),
87 MLXSW_AFK_BLOCK(0x12, mlxsw_sp_afk_element_info_l2_smac_ex
),
88 MLXSW_AFK_BLOCK(0x30, mlxsw_sp_afk_element_info_ipv4_sip
),
89 MLXSW_AFK_BLOCK(0x31, mlxsw_sp_afk_element_info_ipv4_dip
),
90 MLXSW_AFK_BLOCK(0x32, mlxsw_sp_afk_element_info_ipv4
),
91 MLXSW_AFK_BLOCK(0x33, mlxsw_sp_afk_element_info_ipv4_ex
),
92 MLXSW_AFK_BLOCK(0x60, mlxsw_sp_afk_element_info_ipv6_dip
),
93 MLXSW_AFK_BLOCK(0x65, mlxsw_sp_afk_element_info_ipv6_ex1
),
94 MLXSW_AFK_BLOCK(0x62, mlxsw_sp_afk_element_info_ipv6_sip
),
95 MLXSW_AFK_BLOCK(0x63, mlxsw_sp_afk_element_info_ipv6_sip_ex
),
96 MLXSW_AFK_BLOCK(0xB0, mlxsw_sp_afk_element_info_packet_type
),
99 #define MLXSW_SP1_AFK_KEY_BLOCK_SIZE 16
101 static void mlxsw_sp1_afk_encode_block(char *output
, int block_index
,
104 unsigned int offset
= block_index
* MLXSW_SP1_AFK_KEY_BLOCK_SIZE
;
105 char *output_indexed
= output
+ offset
;
107 memcpy(output_indexed
, block
, MLXSW_SP1_AFK_KEY_BLOCK_SIZE
);
110 static void mlxsw_sp1_afk_clear_block(char *output
, int block_index
)
112 unsigned int offset
= block_index
* MLXSW_SP1_AFK_KEY_BLOCK_SIZE
;
113 char *output_indexed
= output
+ offset
;
115 memset(output_indexed
, 0, MLXSW_SP1_AFK_KEY_BLOCK_SIZE
);
118 const struct mlxsw_afk_ops mlxsw_sp1_afk_ops
= {
119 .blocks
= mlxsw_sp1_afk_blocks
,
120 .blocks_count
= ARRAY_SIZE(mlxsw_sp1_afk_blocks
),
121 .encode_block
= mlxsw_sp1_afk_encode_block
,
122 .clear_block
= mlxsw_sp1_afk_clear_block
,
125 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_0
[] = {
126 MLXSW_AFK_ELEMENT_INST_BUF(DMAC_0_31
, 0x04, 4),
129 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_1
[] = {
130 MLXSW_AFK_ELEMENT_INST_BUF(SMAC_0_31
, 0x04, 4),
133 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_2
[] = {
134 MLXSW_AFK_ELEMENT_INST_BUF(SMAC_32_47
, 0x04, 2),
135 MLXSW_AFK_ELEMENT_INST_BUF(DMAC_32_47
, 0x06, 2),
138 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_3
[] = {
139 MLXSW_AFK_ELEMENT_INST_U32(PCP
, 0x00, 0, 3),
140 MLXSW_AFK_ELEMENT_INST_U32(VID
, 0x04, 16, 12),
141 MLXSW_AFK_ELEMENT_INST_BUF(DMAC_32_47
, 0x06, 2),
144 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_4
[] = {
145 MLXSW_AFK_ELEMENT_INST_U32(PCP
, 0x00, 0, 3),
146 MLXSW_AFK_ELEMENT_INST_U32(VID
, 0x04, 16, 12),
147 MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE
, 0x04, 0, 16),
150 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_5
[] = {
151 MLXSW_AFK_ELEMENT_INST_U32(VID
, 0x04, 16, 12),
152 MLXSW_AFK_ELEMENT_INST_EXT_U32(SRC_SYS_PORT
, 0x04, 0, 8, -1, true), /* RX_ACL_SYSTEM_PORT */
155 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_0
[] = {
156 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31
, 0x04, 4),
159 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_1
[] = {
160 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31
, 0x04, 4),
163 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_2
[] = {
164 MLXSW_AFK_ELEMENT_INST_U32(IP_DSCP
, 0x04, 0, 6),
165 MLXSW_AFK_ELEMENT_INST_U32(IP_ECN
, 0x04, 6, 2),
166 MLXSW_AFK_ELEMENT_INST_U32(IP_TTL_
, 0x04, 8, 8),
167 MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO
, 0x04, 16, 8),
170 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_4
[] = {
171 MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_0_7
, 0x04, 24, 8),
172 MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_8_10
, 0x00, 0, 3),
175 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_0
[] = {
176 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_32_63
, 0x04, 4),
179 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_1
[] = {
180 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_64_95
, 0x04, 4),
183 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2
[] = {
184 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_96_127
, 0x04, 4),
187 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_3
[] = {
188 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_32_63
, 0x04, 4),
191 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_4
[] = {
192 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_64_95
, 0x04, 4),
195 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_5
[] = {
196 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_96_127
, 0x04, 4),
199 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l4_0
[] = {
200 MLXSW_AFK_ELEMENT_INST_U32(SRC_L4_PORT
, 0x04, 16, 16),
201 MLXSW_AFK_ELEMENT_INST_U32(DST_L4_PORT
, 0x04, 0, 16),
204 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l4_2
[] = {
205 MLXSW_AFK_ELEMENT_INST_U32(TCP_FLAGS
, 0x04, 16, 9), /* TCP_CONTROL + TCP_ECN */
208 static const struct mlxsw_afk_block mlxsw_sp2_afk_blocks
[] = {
209 MLXSW_AFK_BLOCK(0x10, mlxsw_sp_afk_element_info_mac_0
),
210 MLXSW_AFK_BLOCK(0x11, mlxsw_sp_afk_element_info_mac_1
),
211 MLXSW_AFK_BLOCK(0x12, mlxsw_sp_afk_element_info_mac_2
),
212 MLXSW_AFK_BLOCK(0x13, mlxsw_sp_afk_element_info_mac_3
),
213 MLXSW_AFK_BLOCK(0x14, mlxsw_sp_afk_element_info_mac_4
),
214 MLXSW_AFK_BLOCK(0x15, mlxsw_sp_afk_element_info_mac_5
),
215 MLXSW_AFK_BLOCK(0x38, mlxsw_sp_afk_element_info_ipv4_0
),
216 MLXSW_AFK_BLOCK(0x39, mlxsw_sp_afk_element_info_ipv4_1
),
217 MLXSW_AFK_BLOCK(0x3A, mlxsw_sp_afk_element_info_ipv4_2
),
218 MLXSW_AFK_BLOCK(0x3C, mlxsw_sp_afk_element_info_ipv4_4
),
219 MLXSW_AFK_BLOCK(0x40, mlxsw_sp_afk_element_info_ipv6_0
),
220 MLXSW_AFK_BLOCK(0x41, mlxsw_sp_afk_element_info_ipv6_1
),
221 MLXSW_AFK_BLOCK(0x42, mlxsw_sp_afk_element_info_ipv6_2
),
222 MLXSW_AFK_BLOCK(0x43, mlxsw_sp_afk_element_info_ipv6_3
),
223 MLXSW_AFK_BLOCK(0x44, mlxsw_sp_afk_element_info_ipv6_4
),
224 MLXSW_AFK_BLOCK(0x45, mlxsw_sp_afk_element_info_ipv6_5
),
225 MLXSW_AFK_BLOCK(0x90, mlxsw_sp_afk_element_info_l4_0
),
226 MLXSW_AFK_BLOCK(0x92, mlxsw_sp_afk_element_info_l4_2
),
229 #define MLXSW_SP2_AFK_BITS_PER_BLOCK 36
231 /* A block in Spectrum-2 is of the following form:
233 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
234 * | | | | | | | | | | | | | | | | | | | | | | | | | | | | |35|34|33|32|
235 * +-----------------------------------------------------------------------------------------------+
236 * |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
237 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
239 MLXSW_ITEM64(sp2_afk
, block
, value
, 0x00, 0, MLXSW_SP2_AFK_BITS_PER_BLOCK
);
241 /* The key / mask block layout in Spectrum-2 is of the following form:
243 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
244 * | | | | | | | | | | | | | | | | | block11_high |
245 * +-----------------------------------------------------------------------------------------------+
246 * | block11_low | block10_high |
247 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
251 struct mlxsw_sp2_afk_block_layout
{
252 unsigned short offset
;
253 struct mlxsw_item item
;
256 #define MLXSW_SP2_AFK_BLOCK_LAYOUT(_block, _offset, _shift) \
261 .size = {.bits = MLXSW_SP2_AFK_BITS_PER_BLOCK}, \
266 static const struct mlxsw_sp2_afk_block_layout mlxsw_sp2_afk_blocks_layout[] = {
267 MLXSW_SP2_AFK_BLOCK_LAYOUT(block0
, 0x30, 0),
268 MLXSW_SP2_AFK_BLOCK_LAYOUT(block1
, 0x2C, 4),
269 MLXSW_SP2_AFK_BLOCK_LAYOUT(block2
, 0x28, 8),
270 MLXSW_SP2_AFK_BLOCK_LAYOUT(block3
, 0x24, 12),
271 MLXSW_SP2_AFK_BLOCK_LAYOUT(block4
, 0x20, 16),
272 MLXSW_SP2_AFK_BLOCK_LAYOUT(block5
, 0x1C, 20),
273 MLXSW_SP2_AFK_BLOCK_LAYOUT(block6
, 0x18, 24),
274 MLXSW_SP2_AFK_BLOCK_LAYOUT(block7
, 0x14, 28),
275 MLXSW_SP2_AFK_BLOCK_LAYOUT(block8
, 0x0C, 0),
276 MLXSW_SP2_AFK_BLOCK_LAYOUT(block9
, 0x08, 4),
277 MLXSW_SP2_AFK_BLOCK_LAYOUT(block10
, 0x04, 8),
278 MLXSW_SP2_AFK_BLOCK_LAYOUT(block11
, 0x00, 12),
281 static void __mlxsw_sp2_afk_block_value_set(char *output
, int block_index
,
284 const struct mlxsw_sp2_afk_block_layout
*block_layout
;
286 if (WARN_ON(block_index
< 0 ||
287 block_index
>= ARRAY_SIZE(mlxsw_sp2_afk_blocks_layout
)))
290 block_layout
= &mlxsw_sp2_afk_blocks_layout
[block_index
];
291 __mlxsw_item_set64(output
+ block_layout
->offset
,
292 &block_layout
->item
, 0, block_value
);
295 static void mlxsw_sp2_afk_encode_block(char *output
, int block_index
,
298 u64 block_value
= mlxsw_sp2_afk_block_value_get(block
);
300 __mlxsw_sp2_afk_block_value_set(output
, block_index
, block_value
);
303 static void mlxsw_sp2_afk_clear_block(char *output
, int block_index
)
305 __mlxsw_sp2_afk_block_value_set(output
, block_index
, 0);
308 const struct mlxsw_afk_ops mlxsw_sp2_afk_ops
= {
309 .blocks
= mlxsw_sp2_afk_blocks
,
310 .blocks_count
= ARRAY_SIZE(mlxsw_sp2_afk_blocks
),
311 .encode_block
= mlxsw_sp2_afk_encode_block
,
312 .clear_block
= mlxsw_sp2_afk_clear_block
,