0001
0002
0003
0004 #include <linux/kernel.h>
0005 #include <linux/module.h>
0006 #include "spectrum.h"
0007 #include "item.h"
0008 #include "core_acl_flex_keys.h"
0009
0010 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_dmac[] = {
0011 MLXSW_AFK_ELEMENT_INST_BUF(DMAC_32_47, 0x00, 2),
0012 MLXSW_AFK_ELEMENT_INST_BUF(DMAC_0_31, 0x02, 4),
0013 MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 13, 3),
0014 MLXSW_AFK_ELEMENT_INST_U32(VID, 0x08, 0, 12),
0015 MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16),
0016 };
0017
0018 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_smac[] = {
0019 MLXSW_AFK_ELEMENT_INST_BUF(SMAC_32_47, 0x00, 2),
0020 MLXSW_AFK_ELEMENT_INST_BUF(SMAC_0_31, 0x02, 4),
0021 MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 13, 3),
0022 MLXSW_AFK_ELEMENT_INST_U32(VID, 0x08, 0, 12),
0023 MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16),
0024 };
0025
0026 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_smac_ex[] = {
0027 MLXSW_AFK_ELEMENT_INST_BUF(SMAC_32_47, 0x02, 2),
0028 MLXSW_AFK_ELEMENT_INST_BUF(SMAC_0_31, 0x04, 4),
0029 MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x0C, 0, 16),
0030 };
0031
0032 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_sip[] = {
0033 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x00, 4),
0034 MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),
0035 MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16),
0036 };
0037
0038 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_dip[] = {
0039 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x00, 4),
0040 MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),
0041 MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16),
0042 };
0043
0044 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4[] = {
0045 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x00, 4),
0046 MLXSW_AFK_ELEMENT_INST_U32(IP_ECN, 0x04, 4, 2),
0047 MLXSW_AFK_ELEMENT_INST_U32(IP_TTL_, 0x04, 24, 8),
0048 MLXSW_AFK_ELEMENT_INST_U32(IP_DSCP, 0x08, 0, 6),
0049 MLXSW_AFK_ELEMENT_INST_U32(TCP_FLAGS, 0x08, 8, 9),
0050 };
0051
0052 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_ex[] = {
0053 MLXSW_AFK_ELEMENT_INST_U32(VID, 0x00, 0, 12),
0054 MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 29, 3),
0055 MLXSW_AFK_ELEMENT_INST_U32(SRC_L4_PORT, 0x08, 0, 16),
0056 MLXSW_AFK_ELEMENT_INST_U32(DST_L4_PORT, 0x0C, 0, 16),
0057 };
0058
0059 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_dip[] = {
0060 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_32_63, 0x00, 4),
0061 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x04, 4),
0062 };
0063
0064 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_ex1[] = {
0065 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_96_127, 0x00, 4),
0066 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_64_95, 0x04, 4),
0067 MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),
0068 };
0069
0070 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_sip[] = {
0071 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_32_63, 0x00, 4),
0072 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x04, 4),
0073 };
0074
0075 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_sip_ex[] = {
0076 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_96_127, 0x00, 4),
0077 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_64_95, 0x04, 4),
0078 };
0079
0080 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_packet_type[] = {
0081 MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x00, 0, 16),
0082 };
0083
0084 static const struct mlxsw_afk_block mlxsw_sp1_afk_blocks[] = {
0085 MLXSW_AFK_BLOCK(0x10, mlxsw_sp_afk_element_info_l2_dmac),
0086 MLXSW_AFK_BLOCK(0x11, mlxsw_sp_afk_element_info_l2_smac),
0087 MLXSW_AFK_BLOCK(0x12, mlxsw_sp_afk_element_info_l2_smac_ex),
0088 MLXSW_AFK_BLOCK(0x30, mlxsw_sp_afk_element_info_ipv4_sip),
0089 MLXSW_AFK_BLOCK(0x31, mlxsw_sp_afk_element_info_ipv4_dip),
0090 MLXSW_AFK_BLOCK(0x32, mlxsw_sp_afk_element_info_ipv4),
0091 MLXSW_AFK_BLOCK(0x33, mlxsw_sp_afk_element_info_ipv4_ex),
0092 MLXSW_AFK_BLOCK(0x60, mlxsw_sp_afk_element_info_ipv6_dip),
0093 MLXSW_AFK_BLOCK(0x65, mlxsw_sp_afk_element_info_ipv6_ex1),
0094 MLXSW_AFK_BLOCK(0x62, mlxsw_sp_afk_element_info_ipv6_sip),
0095 MLXSW_AFK_BLOCK(0x63, mlxsw_sp_afk_element_info_ipv6_sip_ex),
0096 MLXSW_AFK_BLOCK(0xB0, mlxsw_sp_afk_element_info_packet_type),
0097 };
0098
0099 #define MLXSW_SP1_AFK_KEY_BLOCK_SIZE 16
0100
0101 static void mlxsw_sp1_afk_encode_block(char *output, int block_index,
0102 char *block)
0103 {
0104 unsigned int offset = block_index * MLXSW_SP1_AFK_KEY_BLOCK_SIZE;
0105 char *output_indexed = output + offset;
0106
0107 memcpy(output_indexed, block, MLXSW_SP1_AFK_KEY_BLOCK_SIZE);
0108 }
0109
0110 static void mlxsw_sp1_afk_clear_block(char *output, int block_index)
0111 {
0112 unsigned int offset = block_index * MLXSW_SP1_AFK_KEY_BLOCK_SIZE;
0113 char *output_indexed = output + offset;
0114
0115 memset(output_indexed, 0, MLXSW_SP1_AFK_KEY_BLOCK_SIZE);
0116 }
0117
0118 const struct mlxsw_afk_ops mlxsw_sp1_afk_ops = {
0119 .blocks = mlxsw_sp1_afk_blocks,
0120 .blocks_count = ARRAY_SIZE(mlxsw_sp1_afk_blocks),
0121 .encode_block = mlxsw_sp1_afk_encode_block,
0122 .clear_block = mlxsw_sp1_afk_clear_block,
0123 };
0124
0125 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_0[] = {
0126 MLXSW_AFK_ELEMENT_INST_BUF(DMAC_0_31, 0x04, 4),
0127 };
0128
0129 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_1[] = {
0130 MLXSW_AFK_ELEMENT_INST_BUF(SMAC_0_31, 0x04, 4),
0131 };
0132
0133 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_2[] = {
0134 MLXSW_AFK_ELEMENT_INST_BUF(SMAC_32_47, 0x04, 2),
0135 MLXSW_AFK_ELEMENT_INST_BUF(DMAC_32_47, 0x06, 2),
0136 };
0137
0138 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_3[] = {
0139 MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x00, 0, 3),
0140 MLXSW_AFK_ELEMENT_INST_U32(VID, 0x04, 16, 12),
0141 MLXSW_AFK_ELEMENT_INST_BUF(DMAC_32_47, 0x06, 2),
0142 };
0143
0144 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_4[] = {
0145 MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x00, 0, 3),
0146 MLXSW_AFK_ELEMENT_INST_U32(VID, 0x04, 16, 12),
0147 MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x04, 0, 16),
0148 };
0149
0150 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_5[] = {
0151 MLXSW_AFK_ELEMENT_INST_U32(VID, 0x04, 16, 12),
0152 MLXSW_AFK_ELEMENT_INST_EXT_U32(SRC_SYS_PORT, 0x04, 0, 8, -1, true),
0153 };
0154
0155 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_0[] = {
0156 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x04, 4),
0157 };
0158
0159 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_1[] = {
0160 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x04, 4),
0161 };
0162
0163 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_2[] = {
0164 MLXSW_AFK_ELEMENT_INST_U32(IP_DSCP, 0x04, 0, 6),
0165 MLXSW_AFK_ELEMENT_INST_U32(IP_ECN, 0x04, 6, 2),
0166 MLXSW_AFK_ELEMENT_INST_U32(IP_TTL_, 0x04, 8, 8),
0167 MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x04, 16, 8),
0168 };
0169
0170 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_4[] = {
0171 MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_LSB, 0x04, 24, 8),
0172 MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_MSB, 0x00, 0, 3),
0173 };
0174
0175 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_0[] = {
0176 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_32_63, 0x04, 4),
0177 };
0178
0179 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_1[] = {
0180 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_64_95, 0x04, 4),
0181 };
0182
0183 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2[] = {
0184 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_96_127, 0x04, 4),
0185 };
0186
0187 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_3[] = {
0188 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_32_63, 0x04, 4),
0189 };
0190
0191 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_4[] = {
0192 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_64_95, 0x04, 4),
0193 };
0194
0195 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_5[] = {
0196 MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_96_127, 0x04, 4),
0197 };
0198
0199 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l4_0[] = {
0200 MLXSW_AFK_ELEMENT_INST_U32(SRC_L4_PORT, 0x04, 16, 16),
0201 MLXSW_AFK_ELEMENT_INST_U32(DST_L4_PORT, 0x04, 0, 16),
0202 };
0203
0204 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l4_2[] = {
0205 MLXSW_AFK_ELEMENT_INST_U32(TCP_FLAGS, 0x04, 16, 9),
0206 };
0207
0208 static const struct mlxsw_afk_block mlxsw_sp2_afk_blocks[] = {
0209 MLXSW_AFK_BLOCK(0x10, mlxsw_sp_afk_element_info_mac_0),
0210 MLXSW_AFK_BLOCK(0x11, mlxsw_sp_afk_element_info_mac_1),
0211 MLXSW_AFK_BLOCK(0x12, mlxsw_sp_afk_element_info_mac_2),
0212 MLXSW_AFK_BLOCK(0x13, mlxsw_sp_afk_element_info_mac_3),
0213 MLXSW_AFK_BLOCK(0x14, mlxsw_sp_afk_element_info_mac_4),
0214 MLXSW_AFK_BLOCK(0x15, mlxsw_sp_afk_element_info_mac_5),
0215 MLXSW_AFK_BLOCK(0x38, mlxsw_sp_afk_element_info_ipv4_0),
0216 MLXSW_AFK_BLOCK(0x39, mlxsw_sp_afk_element_info_ipv4_1),
0217 MLXSW_AFK_BLOCK(0x3A, mlxsw_sp_afk_element_info_ipv4_2),
0218 MLXSW_AFK_BLOCK(0x3C, mlxsw_sp_afk_element_info_ipv4_4),
0219 MLXSW_AFK_BLOCK(0x40, mlxsw_sp_afk_element_info_ipv6_0),
0220 MLXSW_AFK_BLOCK(0x41, mlxsw_sp_afk_element_info_ipv6_1),
0221 MLXSW_AFK_BLOCK(0x42, mlxsw_sp_afk_element_info_ipv6_2),
0222 MLXSW_AFK_BLOCK(0x43, mlxsw_sp_afk_element_info_ipv6_3),
0223 MLXSW_AFK_BLOCK(0x44, mlxsw_sp_afk_element_info_ipv6_4),
0224 MLXSW_AFK_BLOCK(0x45, mlxsw_sp_afk_element_info_ipv6_5),
0225 MLXSW_AFK_BLOCK(0x90, mlxsw_sp_afk_element_info_l4_0),
0226 MLXSW_AFK_BLOCK(0x92, mlxsw_sp_afk_element_info_l4_2),
0227 };
0228
0229 #define MLXSW_SP2_AFK_BITS_PER_BLOCK 36
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239 MLXSW_ITEM64(sp2_afk, block, value, 0x00, 0, MLXSW_SP2_AFK_BITS_PER_BLOCK);
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251 struct mlxsw_sp2_afk_block_layout {
0252 unsigned short offset;
0253 struct mlxsw_item item;
0254 };
0255
0256 #define MLXSW_SP2_AFK_BLOCK_LAYOUT(_block, _offset, _shift) \
0257 { \
0258 .offset = _offset, \
0259 { \
0260 .shift = _shift, \
0261 .size = {.bits = MLXSW_SP2_AFK_BITS_PER_BLOCK}, \
0262 .name = #_block, \
0263 } \
0264 } \
0265
0266 static const struct mlxsw_sp2_afk_block_layout mlxsw_sp2_afk_blocks_layout[] = {
0267 MLXSW_SP2_AFK_BLOCK_LAYOUT(block0, 0x30, 0),
0268 MLXSW_SP2_AFK_BLOCK_LAYOUT(block1, 0x2C, 4),
0269 MLXSW_SP2_AFK_BLOCK_LAYOUT(block2, 0x28, 8),
0270 MLXSW_SP2_AFK_BLOCK_LAYOUT(block3, 0x24, 12),
0271 MLXSW_SP2_AFK_BLOCK_LAYOUT(block4, 0x20, 16),
0272 MLXSW_SP2_AFK_BLOCK_LAYOUT(block5, 0x1C, 20),
0273 MLXSW_SP2_AFK_BLOCK_LAYOUT(block6, 0x18, 24),
0274 MLXSW_SP2_AFK_BLOCK_LAYOUT(block7, 0x14, 28),
0275 MLXSW_SP2_AFK_BLOCK_LAYOUT(block8, 0x0C, 0),
0276 MLXSW_SP2_AFK_BLOCK_LAYOUT(block9, 0x08, 4),
0277 MLXSW_SP2_AFK_BLOCK_LAYOUT(block10, 0x04, 8),
0278 MLXSW_SP2_AFK_BLOCK_LAYOUT(block11, 0x00, 12),
0279 };
0280
0281 static void __mlxsw_sp2_afk_block_value_set(char *output, int block_index,
0282 u64 block_value)
0283 {
0284 const struct mlxsw_sp2_afk_block_layout *block_layout;
0285
0286 if (WARN_ON(block_index < 0 ||
0287 block_index >= ARRAY_SIZE(mlxsw_sp2_afk_blocks_layout)))
0288 return;
0289
0290 block_layout = &mlxsw_sp2_afk_blocks_layout[block_index];
0291 __mlxsw_item_set64(output + block_layout->offset,
0292 &block_layout->item, 0, block_value);
0293 }
0294
0295 static void mlxsw_sp2_afk_encode_block(char *output, int block_index,
0296 char *block)
0297 {
0298 u64 block_value = mlxsw_sp2_afk_block_value_get(block);
0299
0300 __mlxsw_sp2_afk_block_value_set(output, block_index, block_value);
0301 }
0302
0303 static void mlxsw_sp2_afk_clear_block(char *output, int block_index)
0304 {
0305 __mlxsw_sp2_afk_block_value_set(output, block_index, 0);
0306 }
0307
0308 const struct mlxsw_afk_ops mlxsw_sp2_afk_ops = {
0309 .blocks = mlxsw_sp2_afk_blocks,
0310 .blocks_count = ARRAY_SIZE(mlxsw_sp2_afk_blocks),
0311 .encode_block = mlxsw_sp2_afk_encode_block,
0312 .clear_block = mlxsw_sp2_afk_clear_block,
0313 };
0314
0315 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_5b[] = {
0316 MLXSW_AFK_ELEMENT_INST_U32(VID, 0x04, 18, 12),
0317 MLXSW_AFK_ELEMENT_INST_EXT_U32(SRC_SYS_PORT, 0x04, 0, 9, -1, true),
0318 };
0319
0320 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_4b[] = {
0321 MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_LSB, 0x04, 13, 8),
0322 MLXSW_AFK_ELEMENT_INST_EXT_U32(VIRT_ROUTER_MSB, 0x04, 21, 4, 0, true),
0323 };
0324
0325 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2b[] = {
0326 MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_96_127, 0x04, 4),
0327 };
0328
0329 static const struct mlxsw_afk_block mlxsw_sp4_afk_blocks[] = {
0330 MLXSW_AFK_BLOCK(0x10, mlxsw_sp_afk_element_info_mac_0),
0331 MLXSW_AFK_BLOCK(0x11, mlxsw_sp_afk_element_info_mac_1),
0332 MLXSW_AFK_BLOCK(0x12, mlxsw_sp_afk_element_info_mac_2),
0333 MLXSW_AFK_BLOCK(0x13, mlxsw_sp_afk_element_info_mac_3),
0334 MLXSW_AFK_BLOCK(0x14, mlxsw_sp_afk_element_info_mac_4),
0335 MLXSW_AFK_BLOCK(0x1A, mlxsw_sp_afk_element_info_mac_5b),
0336 MLXSW_AFK_BLOCK(0x38, mlxsw_sp_afk_element_info_ipv4_0),
0337 MLXSW_AFK_BLOCK(0x39, mlxsw_sp_afk_element_info_ipv4_1),
0338 MLXSW_AFK_BLOCK(0x3A, mlxsw_sp_afk_element_info_ipv4_2),
0339 MLXSW_AFK_BLOCK(0x35, mlxsw_sp_afk_element_info_ipv4_4b),
0340 MLXSW_AFK_BLOCK(0x40, mlxsw_sp_afk_element_info_ipv6_0),
0341 MLXSW_AFK_BLOCK(0x41, mlxsw_sp_afk_element_info_ipv6_1),
0342 MLXSW_AFK_BLOCK(0x47, mlxsw_sp_afk_element_info_ipv6_2b),
0343 MLXSW_AFK_BLOCK(0x43, mlxsw_sp_afk_element_info_ipv6_3),
0344 MLXSW_AFK_BLOCK(0x44, mlxsw_sp_afk_element_info_ipv6_4),
0345 MLXSW_AFK_BLOCK(0x45, mlxsw_sp_afk_element_info_ipv6_5),
0346 MLXSW_AFK_BLOCK(0x90, mlxsw_sp_afk_element_info_l4_0),
0347 MLXSW_AFK_BLOCK(0x92, mlxsw_sp_afk_element_info_l4_2),
0348 };
0349
0350 const struct mlxsw_afk_ops mlxsw_sp4_afk_ops = {
0351 .blocks = mlxsw_sp4_afk_blocks,
0352 .blocks_count = ARRAY_SIZE(mlxsw_sp4_afk_blocks),
0353 .encode_block = mlxsw_sp2_afk_encode_block,
0354 .clear_block = mlxsw_sp2_afk_clear_block,
0355 };