spectrum_acl_flex_keys.c (14019B)
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2/* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */ 3 4#include <linux/kernel.h> 5#include <linux/module.h> 6#include "spectrum.h" 7#include "item.h" 8#include "core_acl_flex_keys.h" 9 10static 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), 16}; 17 18static 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), 24}; 25 26static 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), 30}; 31 32static 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), 36}; 37 38static 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), 42}; 43 44static 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 */ 50}; 51 52static 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), 57}; 58 59static 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), 62}; 63 64static 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), 68}; 69 70static 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), 73}; 74 75static 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), 78}; 79 80static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_packet_type[] = { 81 MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x00, 0, 16), 82}; 83 84static 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), 97}; 98 99#define MLXSW_SP1_AFK_KEY_BLOCK_SIZE 16 100 101static void mlxsw_sp1_afk_encode_block(char *output, int block_index, 102 char *block) 103{ 104 unsigned int offset = block_index * MLXSW_SP1_AFK_KEY_BLOCK_SIZE; 105 char *output_indexed = output + offset; 106 107 memcpy(output_indexed, block, MLXSW_SP1_AFK_KEY_BLOCK_SIZE); 108} 109 110static void mlxsw_sp1_afk_clear_block(char *output, int block_index) 111{ 112 unsigned int offset = block_index * MLXSW_SP1_AFK_KEY_BLOCK_SIZE; 113 char *output_indexed = output + offset; 114 115 memset(output_indexed, 0, MLXSW_SP1_AFK_KEY_BLOCK_SIZE); 116} 117 118const 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, 123}; 124 125static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_0[] = { 126 MLXSW_AFK_ELEMENT_INST_BUF(DMAC_0_31, 0x04, 4), 127}; 128 129static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_1[] = { 130 MLXSW_AFK_ELEMENT_INST_BUF(SMAC_0_31, 0x04, 4), 131}; 132 133static 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), 136}; 137 138static 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), 142}; 143 144static 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), 148}; 149 150static 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 */ 153}; 154 155static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_0[] = { 156 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x04, 4), 157}; 158 159static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_1[] = { 160 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x04, 4), 161}; 162 163static 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), 168}; 169 170static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_4[] = { 171 MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_LSB, 0x04, 24, 8), 172 MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_MSB, 0x00, 0, 3), 173}; 174 175static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_0[] = { 176 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_32_63, 0x04, 4), 177}; 178 179static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_1[] = { 180 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_64_95, 0x04, 4), 181}; 182 183static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2[] = { 184 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_96_127, 0x04, 4), 185}; 186 187static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_3[] = { 188 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_32_63, 0x04, 4), 189}; 190 191static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_4[] = { 192 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_64_95, 0x04, 4), 193}; 194 195static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_5[] = { 196 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_96_127, 0x04, 4), 197}; 198 199static 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), 202}; 203 204static 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 */ 206}; 207 208static 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), 227}; 228 229#define MLXSW_SP2_AFK_BITS_PER_BLOCK 36 230 231/* A block in Spectrum-2 is of the following form: 232 * 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 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 238 */ 239MLXSW_ITEM64(sp2_afk, block, value, 0x00, 0, MLXSW_SP2_AFK_BITS_PER_BLOCK); 240 241/* The key / mask block layout in Spectrum-2 is of the following form: 242 * 243 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 244 * | | | | | | | | | | | | | | | | | block11_high | 245 * +-----------------------------------------------------------------------------------------------+ 246 * | block11_low | block10_high | 247 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 248 * ... 249 */ 250 251struct mlxsw_sp2_afk_block_layout { 252 unsigned short offset; 253 struct mlxsw_item item; 254}; 255 256#define MLXSW_SP2_AFK_BLOCK_LAYOUT(_block, _offset, _shift) \ 257 { \ 258 .offset = _offset, \ 259 { \ 260 .shift = _shift, \ 261 .size = {.bits = MLXSW_SP2_AFK_BITS_PER_BLOCK}, \ 262 .name = #_block, \ 263 } \ 264 } \ 265 266static 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), 279}; 280 281static void __mlxsw_sp2_afk_block_value_set(char *output, int block_index, 282 u64 block_value) 283{ 284 const struct mlxsw_sp2_afk_block_layout *block_layout; 285 286 if (WARN_ON(block_index < 0 || 287 block_index >= ARRAY_SIZE(mlxsw_sp2_afk_blocks_layout))) 288 return; 289 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); 293} 294 295static void mlxsw_sp2_afk_encode_block(char *output, int block_index, 296 char *block) 297{ 298 u64 block_value = mlxsw_sp2_afk_block_value_get(block); 299 300 __mlxsw_sp2_afk_block_value_set(output, block_index, block_value); 301} 302 303static void mlxsw_sp2_afk_clear_block(char *output, int block_index) 304{ 305 __mlxsw_sp2_afk_block_value_set(output, block_index, 0); 306} 307 308const 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, 313}; 314 315static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_5b[] = { 316 MLXSW_AFK_ELEMENT_INST_U32(VID, 0x04, 18, 12), 317 MLXSW_AFK_ELEMENT_INST_EXT_U32(SRC_SYS_PORT, 0x04, 0, 9, -1, true), /* RX_ACL_SYSTEM_PORT */ 318}; 319 320static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_4b[] = { 321 MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_LSB, 0x04, 13, 8), 322 MLXSW_AFK_ELEMENT_INST_EXT_U32(VIRT_ROUTER_MSB, 0x04, 21, 4, 0, true), 323}; 324 325static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2b[] = { 326 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_96_127, 0x04, 4), 327}; 328 329static const struct mlxsw_afk_block mlxsw_sp4_afk_blocks[] = { 330 MLXSW_AFK_BLOCK(0x10, mlxsw_sp_afk_element_info_mac_0), 331 MLXSW_AFK_BLOCK(0x11, mlxsw_sp_afk_element_info_mac_1), 332 MLXSW_AFK_BLOCK(0x12, mlxsw_sp_afk_element_info_mac_2), 333 MLXSW_AFK_BLOCK(0x13, mlxsw_sp_afk_element_info_mac_3), 334 MLXSW_AFK_BLOCK(0x14, mlxsw_sp_afk_element_info_mac_4), 335 MLXSW_AFK_BLOCK(0x1A, mlxsw_sp_afk_element_info_mac_5b), 336 MLXSW_AFK_BLOCK(0x38, mlxsw_sp_afk_element_info_ipv4_0), 337 MLXSW_AFK_BLOCK(0x39, mlxsw_sp_afk_element_info_ipv4_1), 338 MLXSW_AFK_BLOCK(0x3A, mlxsw_sp_afk_element_info_ipv4_2), 339 MLXSW_AFK_BLOCK(0x35, mlxsw_sp_afk_element_info_ipv4_4b), 340 MLXSW_AFK_BLOCK(0x40, mlxsw_sp_afk_element_info_ipv6_0), 341 MLXSW_AFK_BLOCK(0x41, mlxsw_sp_afk_element_info_ipv6_1), 342 MLXSW_AFK_BLOCK(0x47, mlxsw_sp_afk_element_info_ipv6_2b), 343 MLXSW_AFK_BLOCK(0x43, mlxsw_sp_afk_element_info_ipv6_3), 344 MLXSW_AFK_BLOCK(0x44, mlxsw_sp_afk_element_info_ipv6_4), 345 MLXSW_AFK_BLOCK(0x45, mlxsw_sp_afk_element_info_ipv6_5), 346 MLXSW_AFK_BLOCK(0x90, mlxsw_sp_afk_element_info_l4_0), 347 MLXSW_AFK_BLOCK(0x92, mlxsw_sp_afk_element_info_l4_2), 348}; 349 350const struct mlxsw_afk_ops mlxsw_sp4_afk_ops = { 351 .blocks = mlxsw_sp4_afk_blocks, 352 .blocks_count = ARRAY_SIZE(mlxsw_sp4_afk_blocks), 353 .encode_block = mlxsw_sp2_afk_encode_block, 354 .clear_block = mlxsw_sp2_afk_clear_block, 355};