root/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. mlxsw_afk_element_usage_add
  2. mlxsw_afk_element_usage_zero
  3. mlxsw_afk_element_usage_fill
  4. mlxsw_afk_element_usage_subset

   1 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
   2 /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */
   3 
   4 #ifndef _MLXSW_CORE_ACL_FLEX_KEYS_H
   5 #define _MLXSW_CORE_ACL_FLEX_KEYS_H
   6 
   7 #include <linux/types.h>
   8 #include <linux/bitmap.h>
   9 
  10 #include "item.h"
  11 
  12 enum mlxsw_afk_element {
  13         MLXSW_AFK_ELEMENT_SRC_SYS_PORT,
  14         MLXSW_AFK_ELEMENT_DMAC_32_47,
  15         MLXSW_AFK_ELEMENT_DMAC_0_31,
  16         MLXSW_AFK_ELEMENT_SMAC_32_47,
  17         MLXSW_AFK_ELEMENT_SMAC_0_31,
  18         MLXSW_AFK_ELEMENT_ETHERTYPE,
  19         MLXSW_AFK_ELEMENT_IP_PROTO,
  20         MLXSW_AFK_ELEMENT_SRC_IP_96_127,
  21         MLXSW_AFK_ELEMENT_SRC_IP_64_95,
  22         MLXSW_AFK_ELEMENT_SRC_IP_32_63,
  23         MLXSW_AFK_ELEMENT_SRC_IP_0_31,
  24         MLXSW_AFK_ELEMENT_DST_IP_96_127,
  25         MLXSW_AFK_ELEMENT_DST_IP_64_95,
  26         MLXSW_AFK_ELEMENT_DST_IP_32_63,
  27         MLXSW_AFK_ELEMENT_DST_IP_0_31,
  28         MLXSW_AFK_ELEMENT_DST_L4_PORT,
  29         MLXSW_AFK_ELEMENT_SRC_L4_PORT,
  30         MLXSW_AFK_ELEMENT_VID,
  31         MLXSW_AFK_ELEMENT_PCP,
  32         MLXSW_AFK_ELEMENT_TCP_FLAGS,
  33         MLXSW_AFK_ELEMENT_IP_TTL_,
  34         MLXSW_AFK_ELEMENT_IP_ECN,
  35         MLXSW_AFK_ELEMENT_IP_DSCP,
  36         MLXSW_AFK_ELEMENT_VIRT_ROUTER_8_10,
  37         MLXSW_AFK_ELEMENT_VIRT_ROUTER_0_7,
  38         MLXSW_AFK_ELEMENT_MAX,
  39 };
  40 
  41 enum mlxsw_afk_element_type {
  42         MLXSW_AFK_ELEMENT_TYPE_U32,
  43         MLXSW_AFK_ELEMENT_TYPE_BUF,
  44 };
  45 
  46 struct mlxsw_afk_element_info {
  47         enum mlxsw_afk_element element; /* element ID */
  48         enum mlxsw_afk_element_type type;
  49         struct mlxsw_item item; /* element geometry in internal storage */
  50 };
  51 
  52 #define MLXSW_AFK_ELEMENT_INFO(_type, _element, _offset, _shift, _size)         \
  53         [MLXSW_AFK_ELEMENT_##_element] = {                                      \
  54                 .element = MLXSW_AFK_ELEMENT_##_element,                        \
  55                 .type = _type,                                                  \
  56                 .item = {                                                       \
  57                         .offset = _offset,                                      \
  58                         .shift = _shift,                                        \
  59                         .size = {.bits = _size},                                \
  60                         .name = #_element,                                      \
  61                 },                                                              \
  62         }
  63 
  64 #define MLXSW_AFK_ELEMENT_INFO_U32(_element, _offset, _shift, _size)            \
  65         MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_U32,                      \
  66                                _element, _offset, _shift, _size)
  67 
  68 #define MLXSW_AFK_ELEMENT_INFO_BUF(_element, _offset, _size)                    \
  69         MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_BUF,                      \
  70                                _element, _offset, 0, _size)
  71 
  72 /* For the purpose of the driver, define an internal storage scratchpad
  73  * that will be used to store key/mask values. For each defined element type
  74  * define an internal storage geometry.
  75  */
  76 static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = {
  77         MLXSW_AFK_ELEMENT_INFO_U32(SRC_SYS_PORT, 0x00, 16, 16),
  78         MLXSW_AFK_ELEMENT_INFO_BUF(DMAC_32_47, 0x04, 2),
  79         MLXSW_AFK_ELEMENT_INFO_BUF(DMAC_0_31, 0x06, 4),
  80         MLXSW_AFK_ELEMENT_INFO_BUF(SMAC_32_47, 0x0A, 2),
  81         MLXSW_AFK_ELEMENT_INFO_BUF(SMAC_0_31, 0x0C, 4),
  82         MLXSW_AFK_ELEMENT_INFO_U32(ETHERTYPE, 0x00, 0, 16),
  83         MLXSW_AFK_ELEMENT_INFO_U32(IP_PROTO, 0x10, 0, 8),
  84         MLXSW_AFK_ELEMENT_INFO_U32(VID, 0x10, 8, 12),
  85         MLXSW_AFK_ELEMENT_INFO_U32(PCP, 0x10, 20, 3),
  86         MLXSW_AFK_ELEMENT_INFO_U32(TCP_FLAGS, 0x10, 23, 9),
  87         MLXSW_AFK_ELEMENT_INFO_U32(DST_L4_PORT, 0x14, 0, 16),
  88         MLXSW_AFK_ELEMENT_INFO_U32(SRC_L4_PORT, 0x14, 16, 16),
  89         MLXSW_AFK_ELEMENT_INFO_U32(IP_TTL_, 0x18, 0, 8),
  90         MLXSW_AFK_ELEMENT_INFO_U32(IP_ECN, 0x18, 9, 2),
  91         MLXSW_AFK_ELEMENT_INFO_U32(IP_DSCP, 0x18, 11, 6),
  92         MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_8_10, 0x18, 17, 3),
  93         MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_0_7, 0x18, 20, 8),
  94         MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_96_127, 0x20, 4),
  95         MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_64_95, 0x24, 4),
  96         MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_32_63, 0x28, 4),
  97         MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_0_31, 0x2C, 4),
  98         MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_96_127, 0x30, 4),
  99         MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_64_95, 0x34, 4),
 100         MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_32_63, 0x38, 4),
 101         MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_0_31, 0x3C, 4),
 102 };
 103 
 104 #define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x40
 105 
 106 struct mlxsw_afk_element_inst { /* element instance in actual block */
 107         const struct mlxsw_afk_element_info *info;
 108         enum mlxsw_afk_element_type type;
 109         struct mlxsw_item item; /* element geometry in block */
 110         int u32_key_diff; /* in case value needs to be adjusted before write
 111                            * this diff is here to handle that
 112                            */
 113         bool avoid_size_check;
 114 };
 115 
 116 #define MLXSW_AFK_ELEMENT_INST(_type, _element, _offset,                        \
 117                                _shift, _size, _u32_key_diff, _avoid_size_check) \
 118         {                                                                       \
 119                 .info = &mlxsw_afk_element_infos[MLXSW_AFK_ELEMENT_##_element], \
 120                 .type = _type,                                                  \
 121                 .item = {                                                       \
 122                         .offset = _offset,                                      \
 123                         .shift = _shift,                                        \
 124                         .size = {.bits = _size},                                \
 125                         .name = #_element,                                      \
 126                 },                                                              \
 127                 .u32_key_diff = _u32_key_diff,                                  \
 128                 .avoid_size_check = _avoid_size_check,                          \
 129         }
 130 
 131 #define MLXSW_AFK_ELEMENT_INST_U32(_element, _offset, _shift, _size)            \
 132         MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32,                      \
 133                                _element, _offset, _shift, _size, 0, false)
 134 
 135 #define MLXSW_AFK_ELEMENT_INST_EXT_U32(_element, _offset,                       \
 136                                        _shift, _size, _key_diff,                \
 137                                        _avoid_size_check)                       \
 138         MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32,                      \
 139                                _element, _offset, _shift, _size,                \
 140                                _key_diff, _avoid_size_check)
 141 
 142 #define MLXSW_AFK_ELEMENT_INST_BUF(_element, _offset, _size)                    \
 143         MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_BUF,                      \
 144                                _element, _offset, 0, _size, 0, false)
 145 
 146 struct mlxsw_afk_block {
 147         u16 encoding; /* block ID */
 148         struct mlxsw_afk_element_inst *instances;
 149         unsigned int instances_count;
 150 };
 151 
 152 #define MLXSW_AFK_BLOCK(_encoding, _instances)                                  \
 153         {                                                                       \
 154                 .encoding = _encoding,                                          \
 155                 .instances = _instances,                                        \
 156                 .instances_count = ARRAY_SIZE(_instances),                      \
 157         }
 158 
 159 struct mlxsw_afk_element_usage {
 160         DECLARE_BITMAP(usage, MLXSW_AFK_ELEMENT_MAX);
 161 };
 162 
 163 #define mlxsw_afk_element_usage_for_each(element, elusage)                      \
 164         for_each_set_bit(element, (elusage)->usage, MLXSW_AFK_ELEMENT_MAX)
 165 
 166 static inline void
 167 mlxsw_afk_element_usage_add(struct mlxsw_afk_element_usage *elusage,
 168                             enum mlxsw_afk_element element)
 169 {
 170         __set_bit(element, elusage->usage);
 171 }
 172 
 173 static inline void
 174 mlxsw_afk_element_usage_zero(struct mlxsw_afk_element_usage *elusage)
 175 {
 176         bitmap_zero(elusage->usage, MLXSW_AFK_ELEMENT_MAX);
 177 }
 178 
 179 static inline void
 180 mlxsw_afk_element_usage_fill(struct mlxsw_afk_element_usage *elusage,
 181                              const enum mlxsw_afk_element *elements,
 182                              unsigned int elements_count)
 183 {
 184         int i;
 185 
 186         mlxsw_afk_element_usage_zero(elusage);
 187         for (i = 0; i < elements_count; i++)
 188                 mlxsw_afk_element_usage_add(elusage, elements[i]);
 189 }
 190 
 191 static inline bool
 192 mlxsw_afk_element_usage_subset(struct mlxsw_afk_element_usage *elusage_small,
 193                                struct mlxsw_afk_element_usage *elusage_big)
 194 {
 195         int i;
 196 
 197         for (i = 0; i < MLXSW_AFK_ELEMENT_MAX; i++)
 198                 if (test_bit(i, elusage_small->usage) &&
 199                     !test_bit(i, elusage_big->usage))
 200                         return false;
 201         return true;
 202 }
 203 
 204 struct mlxsw_afk;
 205 
 206 struct mlxsw_afk_ops {
 207         const struct mlxsw_afk_block *blocks;
 208         unsigned int blocks_count;
 209         void (*encode_block)(char *output, int block_index, char *block);
 210         void (*clear_block)(char *output, int block_index);
 211 };
 212 
 213 struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
 214                                    const struct mlxsw_afk_ops *ops);
 215 void mlxsw_afk_destroy(struct mlxsw_afk *mlxsw_afk);
 216 
 217 struct mlxsw_afk_key_info;
 218 
 219 struct mlxsw_afk_key_info *
 220 mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk,
 221                        struct mlxsw_afk_element_usage *elusage);
 222 void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info);
 223 bool mlxsw_afk_key_info_subset(struct mlxsw_afk_key_info *key_info,
 224                                struct mlxsw_afk_element_usage *elusage);
 225 
 226 u16
 227 mlxsw_afk_key_info_block_encoding_get(const struct mlxsw_afk_key_info *key_info,
 228                                       int block_index);
 229 unsigned int
 230 mlxsw_afk_key_info_blocks_count_get(const struct mlxsw_afk_key_info *key_info);
 231 
 232 struct mlxsw_afk_element_values {
 233         struct mlxsw_afk_element_usage elusage;
 234         struct {
 235                 char key[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
 236                 char mask[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
 237         } storage;
 238 };
 239 
 240 void mlxsw_afk_values_add_u32(struct mlxsw_afk_element_values *values,
 241                               enum mlxsw_afk_element element,
 242                               u32 key_value, u32 mask_value);
 243 void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values,
 244                               enum mlxsw_afk_element element,
 245                               const char *key_value, const char *mask_value,
 246                               unsigned int len);
 247 void mlxsw_afk_encode(struct mlxsw_afk *mlxsw_afk,
 248                       struct mlxsw_afk_key_info *key_info,
 249                       struct mlxsw_afk_element_values *values,
 250                       char *key, char *mask);
 251 void mlxsw_afk_clear(struct mlxsw_afk *mlxsw_afk, char *key,
 252                      int block_start, int block_end);
 253 
 254 #endif

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