root/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mlxsw_sp1_afk_encode_block
  2. mlxsw_sp1_afk_clear_block
  3. __mlxsw_sp2_afk_block_value_set
  4. mlxsw_sp2_afk_encode_block
  5. mlxsw_sp2_afk_clear_block

   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 
  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),
  16 };
  17 
  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),
  24 };
  25 
  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),
  30 };
  31 
  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),
  36 };
  37 
  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),
  42 };
  43 
  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 */
  50 };
  51 
  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),
  57 };
  58 
  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),
  62 };
  63 
  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),
  68 };
  69 
  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),
  73 };
  74 
  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),
  78 };
  79 
  80 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_packet_type[] = {
  81         MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x00, 0, 16),
  82 };
  83 
  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),
  97 };
  98 
  99 #define MLXSW_SP1_AFK_KEY_BLOCK_SIZE 16
 100 
 101 static 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 
 110 static 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 
 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,
 123 };
 124 
 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),
 127 };
 128 
 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),
 131 };
 132 
 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),
 136 };
 137 
 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),
 142 };
 143 
 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),
 148 };
 149 
 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 */
 153 };
 154 
 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),
 157 };
 158 
 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),
 161 };
 162 
 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),
 168 };
 169 
 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),
 173 };
 174 
 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),
 177 };
 178 
 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),
 181 };
 182 
 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),
 185 };
 186 
 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),
 189 };
 190 
 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),
 193 };
 194 
 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),
 197 };
 198 
 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),
 202 };
 203 
 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 */
 206 };
 207 
 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),
 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  */
 239 MLXSW_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 
 251 struct 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 
 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),
 279 };
 280 
 281 static 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 
 295 static 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 
 303 static 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 
 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,
 313 };

/* [<][>][^][v][top][bottom][index][help] */