363 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/* 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(L4_PORT_RANGE, 0x04, 16, 16),35 MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),36 MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16),37};38 39static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_dip[] = {40 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x00, 4),41 MLXSW_AFK_ELEMENT_INST_U32(L4_PORT_RANGE, 0x04, 16, 16),42 MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),43 MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16),44};45 46static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4[] = {47 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x00, 4),48 MLXSW_AFK_ELEMENT_INST_U32(IP_ECN, 0x04, 4, 2),49 MLXSW_AFK_ELEMENT_INST_U32(IP_TTL_, 0x04, 24, 8),50 MLXSW_AFK_ELEMENT_INST_U32(IP_DSCP, 0x08, 0, 6),51 MLXSW_AFK_ELEMENT_INST_U32(TCP_FLAGS, 0x08, 8, 9), /* TCP_CONTROL+TCP_ECN */52};53 54static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_ex[] = {55 MLXSW_AFK_ELEMENT_INST_U32(VID, 0x00, 0, 12),56 MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 29, 3),57 MLXSW_AFK_ELEMENT_INST_U32(SRC_L4_PORT, 0x08, 0, 16),58 MLXSW_AFK_ELEMENT_INST_U32(DST_L4_PORT, 0x0C, 0, 16),59};60 61static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_dip[] = {62 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_32_63, 0x00, 4),63 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x04, 4),64};65 66static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_ex1[] = {67 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_96_127, 0x00, 4),68 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_64_95, 0x04, 4),69 MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),70};71 72static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_sip[] = {73 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_32_63, 0x00, 4),74 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x04, 4),75};76 77static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_sip_ex[] = {78 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_96_127, 0x00, 4),79 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_64_95, 0x04, 4),80};81 82static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_packet_type[] = {83 MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x00, 0, 16),84};85 86static const struct mlxsw_afk_block mlxsw_sp1_afk_blocks[] = {87 MLXSW_AFK_BLOCK(0x10, mlxsw_sp_afk_element_info_l2_dmac),88 MLXSW_AFK_BLOCK(0x11, mlxsw_sp_afk_element_info_l2_smac),89 MLXSW_AFK_BLOCK(0x12, mlxsw_sp_afk_element_info_l2_smac_ex),90 MLXSW_AFK_BLOCK(0x30, mlxsw_sp_afk_element_info_ipv4_sip),91 MLXSW_AFK_BLOCK(0x31, mlxsw_sp_afk_element_info_ipv4_dip),92 MLXSW_AFK_BLOCK(0x32, mlxsw_sp_afk_element_info_ipv4),93 MLXSW_AFK_BLOCK(0x33, mlxsw_sp_afk_element_info_ipv4_ex),94 MLXSW_AFK_BLOCK(0x60, mlxsw_sp_afk_element_info_ipv6_dip),95 MLXSW_AFK_BLOCK(0x65, mlxsw_sp_afk_element_info_ipv6_ex1),96 MLXSW_AFK_BLOCK(0x62, mlxsw_sp_afk_element_info_ipv6_sip),97 MLXSW_AFK_BLOCK(0x63, mlxsw_sp_afk_element_info_ipv6_sip_ex),98 MLXSW_AFK_BLOCK(0xB0, mlxsw_sp_afk_element_info_packet_type),99};100 101#define MLXSW_SP1_AFK_KEY_BLOCK_SIZE 16102 103static void mlxsw_sp1_afk_encode_block(char *output, int block_index,104 char *block)105{106 unsigned int offset = block_index * MLXSW_SP1_AFK_KEY_BLOCK_SIZE;107 char *output_indexed = output + offset;108 109 memcpy(output_indexed, block, MLXSW_SP1_AFK_KEY_BLOCK_SIZE);110}111 112static void mlxsw_sp1_afk_clear_block(char *output, int block_index)113{114 unsigned int offset = block_index * MLXSW_SP1_AFK_KEY_BLOCK_SIZE;115 char *output_indexed = output + offset;116 117 memset(output_indexed, 0, MLXSW_SP1_AFK_KEY_BLOCK_SIZE);118}119 120const struct mlxsw_afk_ops mlxsw_sp1_afk_ops = {121 .blocks = mlxsw_sp1_afk_blocks,122 .blocks_count = ARRAY_SIZE(mlxsw_sp1_afk_blocks),123 .encode_block = mlxsw_sp1_afk_encode_block,124 .clear_block = mlxsw_sp1_afk_clear_block,125};126 127static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_0[] = {128 MLXSW_AFK_ELEMENT_INST_U32(FDB_MISS, 0x00, 3, 1),129 MLXSW_AFK_ELEMENT_INST_BUF(DMAC_0_31, 0x04, 4),130};131 132static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_1[] = {133 MLXSW_AFK_ELEMENT_INST_U32(FDB_MISS, 0x00, 3, 1),134 MLXSW_AFK_ELEMENT_INST_BUF(SMAC_0_31, 0x04, 4),135};136 137static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_2[] = {138 MLXSW_AFK_ELEMENT_INST_BUF(SMAC_32_47, 0x04, 2),139 MLXSW_AFK_ELEMENT_INST_BUF(DMAC_32_47, 0x06, 2),140};141 142static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_3[] = {143 MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x00, 0, 3),144 MLXSW_AFK_ELEMENT_INST_U32(VID, 0x04, 16, 12),145 MLXSW_AFK_ELEMENT_INST_BUF(DMAC_32_47, 0x06, 2),146};147 148static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_4[] = {149 MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x00, 0, 3),150 MLXSW_AFK_ELEMENT_INST_U32(VID, 0x04, 16, 12),151 MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x04, 0, 16),152};153 154static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_5[] = {155 MLXSW_AFK_ELEMENT_INST_U32(VID, 0x04, 16, 12),156 MLXSW_AFK_ELEMENT_INST_EXT_U32(SRC_SYS_PORT, 0x04, 0, 8, -1, true), /* RX_ACL_SYSTEM_PORT */157};158 159static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_0[] = {160 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x04, 4),161};162 163static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_1[] = {164 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x04, 4),165};166 167static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_2[] = {168 MLXSW_AFK_ELEMENT_INST_U32(IP_DSCP, 0x04, 0, 6),169 MLXSW_AFK_ELEMENT_INST_U32(IP_ECN, 0x04, 6, 2),170 MLXSW_AFK_ELEMENT_INST_U32(IP_TTL_, 0x04, 8, 8),171 MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x04, 16, 8),172};173 174static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_5[] = {175 MLXSW_AFK_ELEMENT_INST_EXT_U32(VIRT_ROUTER, 0x04, 20, 11, 0, true),176};177 178static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_0[] = {179 MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_0_3, 0x00, 0, 4),180 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_32_63, 0x04, 4),181};182 183static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_1[] = {184 MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_4_7, 0x00, 0, 4),185 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_64_95, 0x04, 4),186};187 188static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2[] = {189 MLXSW_AFK_ELEMENT_INST_EXT_U32(VIRT_ROUTER_MSB, 0x00, 0, 3, 0, true),190 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_96_127, 0x04, 4),191};192 193static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_3[] = {194 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_32_63, 0x04, 4),195};196 197static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_4[] = {198 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_64_95, 0x04, 4),199};200 201static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_5[] = {202 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_96_127, 0x04, 4),203};204 205static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l4_0[] = {206 MLXSW_AFK_ELEMENT_INST_U32(SRC_L4_PORT, 0x04, 16, 16),207 MLXSW_AFK_ELEMENT_INST_U32(DST_L4_PORT, 0x04, 0, 16),208};209 210static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l4_2[] = {211 MLXSW_AFK_ELEMENT_INST_U32(TCP_FLAGS, 0x04, 16, 9), /* TCP_CONTROL + TCP_ECN */212 MLXSW_AFK_ELEMENT_INST_U32(L4_PORT_RANGE, 0x04, 0, 16),213};214 215static const struct mlxsw_afk_block mlxsw_sp2_afk_blocks[] = {216 MLXSW_AFK_BLOCK(0x10, mlxsw_sp_afk_element_info_mac_0),217 MLXSW_AFK_BLOCK(0x11, mlxsw_sp_afk_element_info_mac_1),218 MLXSW_AFK_BLOCK(0x12, mlxsw_sp_afk_element_info_mac_2),219 MLXSW_AFK_BLOCK(0x13, mlxsw_sp_afk_element_info_mac_3),220 MLXSW_AFK_BLOCK(0x14, mlxsw_sp_afk_element_info_mac_4),221 MLXSW_AFK_BLOCK(0x15, mlxsw_sp_afk_element_info_mac_5),222 MLXSW_AFK_BLOCK(0x38, mlxsw_sp_afk_element_info_ipv4_0),223 MLXSW_AFK_BLOCK(0x39, mlxsw_sp_afk_element_info_ipv4_1),224 MLXSW_AFK_BLOCK(0x3A, mlxsw_sp_afk_element_info_ipv4_2),225 MLXSW_AFK_BLOCK(0x3D, mlxsw_sp_afk_element_info_ipv4_5),226 MLXSW_AFK_BLOCK(0x40, mlxsw_sp_afk_element_info_ipv6_0),227 MLXSW_AFK_BLOCK(0x41, mlxsw_sp_afk_element_info_ipv6_1),228 MLXSW_AFK_BLOCK(0x42, mlxsw_sp_afk_element_info_ipv6_2),229 MLXSW_AFK_BLOCK(0x43, mlxsw_sp_afk_element_info_ipv6_3),230 MLXSW_AFK_BLOCK(0x44, mlxsw_sp_afk_element_info_ipv6_4),231 MLXSW_AFK_BLOCK(0x45, mlxsw_sp_afk_element_info_ipv6_5),232 MLXSW_AFK_BLOCK(0x90, mlxsw_sp_afk_element_info_l4_0),233 MLXSW_AFK_BLOCK(0x92, mlxsw_sp_afk_element_info_l4_2),234};235 236#define MLXSW_SP2_AFK_BITS_PER_BLOCK 36237 238/* A block in Spectrum-2 is of the following form:239 *240 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+241 * | | | | | | | | | | | | | | | | | | | | | | | | | | | | |35|34|33|32|242 * +-----------------------------------------------------------------------------------------------+243 * |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|244 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+245 */246MLXSW_ITEM64(sp2_afk, block, value, 0x00, 0, MLXSW_SP2_AFK_BITS_PER_BLOCK);247 248/* The key / mask block layout in Spectrum-2 is of the following form:249 *250 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+251 * | | | | | | | | | | | | | | | | | block11_high |252 * +-----------------------------------------------------------------------------------------------+253 * | block11_low | block10_high |254 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+255 * ...256 */257 258struct mlxsw_sp2_afk_block_layout {259 unsigned short offset;260 struct mlxsw_item item;261};262 263#define MLXSW_SP2_AFK_BLOCK_LAYOUT(_block, _offset, _shift) \264 { \265 .offset = _offset, \266 { \267 .shift = _shift, \268 .size = {.bits = MLXSW_SP2_AFK_BITS_PER_BLOCK}, \269 .name = #_block, \270 } \271 } \272 273static const struct mlxsw_sp2_afk_block_layout mlxsw_sp2_afk_blocks_layout[] = {274 MLXSW_SP2_AFK_BLOCK_LAYOUT(block0, 0x30, 0),275 MLXSW_SP2_AFK_BLOCK_LAYOUT(block1, 0x2C, 4),276 MLXSW_SP2_AFK_BLOCK_LAYOUT(block2, 0x28, 8),277 MLXSW_SP2_AFK_BLOCK_LAYOUT(block3, 0x24, 12),278 MLXSW_SP2_AFK_BLOCK_LAYOUT(block4, 0x20, 16),279 MLXSW_SP2_AFK_BLOCK_LAYOUT(block5, 0x1C, 20),280 MLXSW_SP2_AFK_BLOCK_LAYOUT(block6, 0x18, 24),281 MLXSW_SP2_AFK_BLOCK_LAYOUT(block7, 0x14, 28),282 MLXSW_SP2_AFK_BLOCK_LAYOUT(block8, 0x0C, 0),283 MLXSW_SP2_AFK_BLOCK_LAYOUT(block9, 0x08, 4),284 MLXSW_SP2_AFK_BLOCK_LAYOUT(block10, 0x04, 8),285 MLXSW_SP2_AFK_BLOCK_LAYOUT(block11, 0x00, 12),286};287 288static void __mlxsw_sp2_afk_block_value_set(char *output, int block_index,289 u64 block_value)290{291 const struct mlxsw_sp2_afk_block_layout *block_layout;292 293 if (WARN_ON(block_index < 0 ||294 block_index >= ARRAY_SIZE(mlxsw_sp2_afk_blocks_layout)))295 return;296 297 block_layout = &mlxsw_sp2_afk_blocks_layout[block_index];298 __mlxsw_item_set64(output + block_layout->offset,299 &block_layout->item, 0, block_value);300}301 302static void mlxsw_sp2_afk_encode_block(char *output, int block_index,303 char *block)304{305 u64 block_value = mlxsw_sp2_afk_block_value_get(block);306 307 __mlxsw_sp2_afk_block_value_set(output, block_index, block_value);308}309 310static void mlxsw_sp2_afk_clear_block(char *output, int block_index)311{312 __mlxsw_sp2_afk_block_value_set(output, block_index, 0);313}314 315const struct mlxsw_afk_ops mlxsw_sp2_afk_ops = {316 .blocks = mlxsw_sp2_afk_blocks,317 .blocks_count = ARRAY_SIZE(mlxsw_sp2_afk_blocks),318 .encode_block = mlxsw_sp2_afk_encode_block,319 .clear_block = mlxsw_sp2_afk_clear_block,320};321 322static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_5b[] = {323 MLXSW_AFK_ELEMENT_INST_U32(VID, 0x04, 18, 12),324 MLXSW_AFK_ELEMENT_INST_EXT_U32(SRC_SYS_PORT, 0x04, 0, 9, -1, true), /* RX_ACL_SYSTEM_PORT */325};326 327static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_5b[] = {328 MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER, 0x04, 20, 12),329};330 331static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2b[] = {332 MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_MSB, 0x00, 0, 4),333 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_96_127, 0x04, 4),334};335 336static const struct mlxsw_afk_block mlxsw_sp4_afk_blocks[] = {337 MLXSW_AFK_BLOCK_HIGH_ENTROPY(0x10, mlxsw_sp_afk_element_info_mac_0),338 MLXSW_AFK_BLOCK_HIGH_ENTROPY(0x11, mlxsw_sp_afk_element_info_mac_1),339 MLXSW_AFK_BLOCK(0x12, mlxsw_sp_afk_element_info_mac_2),340 MLXSW_AFK_BLOCK(0x13, mlxsw_sp_afk_element_info_mac_3),341 MLXSW_AFK_BLOCK(0x14, mlxsw_sp_afk_element_info_mac_4),342 MLXSW_AFK_BLOCK_HIGH_ENTROPY(0x1A, mlxsw_sp_afk_element_info_mac_5b),343 MLXSW_AFK_BLOCK_HIGH_ENTROPY(0x38, mlxsw_sp_afk_element_info_ipv4_0),344 MLXSW_AFK_BLOCK_HIGH_ENTROPY(0x39, mlxsw_sp_afk_element_info_ipv4_1),345 MLXSW_AFK_BLOCK(0x3A, mlxsw_sp_afk_element_info_ipv4_2),346 MLXSW_AFK_BLOCK(0x36, mlxsw_sp_afk_element_info_ipv4_5b),347 MLXSW_AFK_BLOCK(0x40, mlxsw_sp_afk_element_info_ipv6_0),348 MLXSW_AFK_BLOCK(0x41, mlxsw_sp_afk_element_info_ipv6_1),349 MLXSW_AFK_BLOCK(0x47, mlxsw_sp_afk_element_info_ipv6_2b),350 MLXSW_AFK_BLOCK(0x43, mlxsw_sp_afk_element_info_ipv6_3),351 MLXSW_AFK_BLOCK(0x44, mlxsw_sp_afk_element_info_ipv6_4),352 MLXSW_AFK_BLOCK(0x45, mlxsw_sp_afk_element_info_ipv6_5),353 MLXSW_AFK_BLOCK_HIGH_ENTROPY(0x90, mlxsw_sp_afk_element_info_l4_0),354 MLXSW_AFK_BLOCK(0x92, mlxsw_sp_afk_element_info_l4_2),355};356 357const struct mlxsw_afk_ops mlxsw_sp4_afk_ops = {358 .blocks = mlxsw_sp4_afk_blocks,359 .blocks_count = ARRAY_SIZE(mlxsw_sp4_afk_blocks),360 .encode_block = mlxsw_sp2_afk_encode_block,361 .clear_block = mlxsw_sp2_afk_clear_block,362};363