linux/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h
<<
>>
Prefs
   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
  12enum 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
  41enum mlxsw_afk_element_type {
  42        MLXSW_AFK_ELEMENT_TYPE_U32,
  43        MLXSW_AFK_ELEMENT_TYPE_BUF,
  44};
  45
  46struct 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#define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x40
  73
  74struct mlxsw_afk_element_inst { /* element instance in actual block */
  75        enum mlxsw_afk_element element;
  76        enum mlxsw_afk_element_type type;
  77        struct mlxsw_item item; /* element geometry in block */
  78        int u32_key_diff; /* in case value needs to be adjusted before write
  79                           * this diff is here to handle that
  80                           */
  81        bool avoid_size_check;
  82};
  83
  84#define MLXSW_AFK_ELEMENT_INST(_type, _element, _offset,                        \
  85                               _shift, _size, _u32_key_diff, _avoid_size_check) \
  86        {                                                                       \
  87                .element = MLXSW_AFK_ELEMENT_##_element,                        \
  88                .type = _type,                                                  \
  89                .item = {                                                       \
  90                        .offset = _offset,                                      \
  91                        .shift = _shift,                                        \
  92                        .size = {.bits = _size},                                \
  93                        .name = #_element,                                      \
  94                },                                                              \
  95                .u32_key_diff = _u32_key_diff,                                  \
  96                .avoid_size_check = _avoid_size_check,                          \
  97        }
  98
  99#define MLXSW_AFK_ELEMENT_INST_U32(_element, _offset, _shift, _size)            \
 100        MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32,                      \
 101                               _element, _offset, _shift, _size, 0, false)
 102
 103#define MLXSW_AFK_ELEMENT_INST_EXT_U32(_element, _offset,                       \
 104                                       _shift, _size, _key_diff,                \
 105                                       _avoid_size_check)                       \
 106        MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32,                      \
 107                               _element, _offset, _shift, _size,                \
 108                               _key_diff, _avoid_size_check)
 109
 110#define MLXSW_AFK_ELEMENT_INST_BUF(_element, _offset, _size)                    \
 111        MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_BUF,                      \
 112                               _element, _offset, 0, _size, 0, false)
 113
 114struct mlxsw_afk_block {
 115        u16 encoding; /* block ID */
 116        struct mlxsw_afk_element_inst *instances;
 117        unsigned int instances_count;
 118};
 119
 120#define MLXSW_AFK_BLOCK(_encoding, _instances)                                  \
 121        {                                                                       \
 122                .encoding = _encoding,                                          \
 123                .instances = _instances,                                        \
 124                .instances_count = ARRAY_SIZE(_instances),                      \
 125        }
 126
 127struct mlxsw_afk_element_usage {
 128        DECLARE_BITMAP(usage, MLXSW_AFK_ELEMENT_MAX);
 129};
 130
 131#define mlxsw_afk_element_usage_for_each(element, elusage)                      \
 132        for_each_set_bit(element, (elusage)->usage, MLXSW_AFK_ELEMENT_MAX)
 133
 134static inline void
 135mlxsw_afk_element_usage_add(struct mlxsw_afk_element_usage *elusage,
 136                            enum mlxsw_afk_element element)
 137{
 138        __set_bit(element, elusage->usage);
 139}
 140
 141static inline void
 142mlxsw_afk_element_usage_zero(struct mlxsw_afk_element_usage *elusage)
 143{
 144        bitmap_zero(elusage->usage, MLXSW_AFK_ELEMENT_MAX);
 145}
 146
 147static inline void
 148mlxsw_afk_element_usage_fill(struct mlxsw_afk_element_usage *elusage,
 149                             const enum mlxsw_afk_element *elements,
 150                             unsigned int elements_count)
 151{
 152        int i;
 153
 154        mlxsw_afk_element_usage_zero(elusage);
 155        for (i = 0; i < elements_count; i++)
 156                mlxsw_afk_element_usage_add(elusage, elements[i]);
 157}
 158
 159static inline bool
 160mlxsw_afk_element_usage_subset(struct mlxsw_afk_element_usage *elusage_small,
 161                               struct mlxsw_afk_element_usage *elusage_big)
 162{
 163        int i;
 164
 165        for (i = 0; i < MLXSW_AFK_ELEMENT_MAX; i++)
 166                if (test_bit(i, elusage_small->usage) &&
 167                    !test_bit(i, elusage_big->usage))
 168                        return false;
 169        return true;
 170}
 171
 172struct mlxsw_afk;
 173
 174struct mlxsw_afk_ops {
 175        const struct mlxsw_afk_block *blocks;
 176        unsigned int blocks_count;
 177        void (*encode_block)(char *output, int block_index, char *block);
 178        void (*clear_block)(char *output, int block_index);
 179};
 180
 181struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
 182                                   const struct mlxsw_afk_ops *ops);
 183void mlxsw_afk_destroy(struct mlxsw_afk *mlxsw_afk);
 184
 185struct mlxsw_afk_key_info;
 186
 187struct mlxsw_afk_key_info *
 188mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk,
 189                       struct mlxsw_afk_element_usage *elusage);
 190void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info);
 191bool mlxsw_afk_key_info_subset(struct mlxsw_afk_key_info *key_info,
 192                               struct mlxsw_afk_element_usage *elusage);
 193
 194u16
 195mlxsw_afk_key_info_block_encoding_get(const struct mlxsw_afk_key_info *key_info,
 196                                      int block_index);
 197unsigned int
 198mlxsw_afk_key_info_blocks_count_get(const struct mlxsw_afk_key_info *key_info);
 199
 200struct mlxsw_afk_element_values {
 201        struct mlxsw_afk_element_usage elusage;
 202        struct {
 203                char key[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
 204                char mask[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
 205        } storage;
 206};
 207
 208void mlxsw_afk_values_add_u32(struct mlxsw_afk_element_values *values,
 209                              enum mlxsw_afk_element element,
 210                              u32 key_value, u32 mask_value);
 211void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values,
 212                              enum mlxsw_afk_element element,
 213                              const char *key_value, const char *mask_value,
 214                              unsigned int len);
 215void mlxsw_afk_encode(struct mlxsw_afk *mlxsw_afk,
 216                      struct mlxsw_afk_key_info *key_info,
 217                      struct mlxsw_afk_element_values *values,
 218                      char *key, char *mask);
 219void mlxsw_afk_clear(struct mlxsw_afk *mlxsw_afk, char *key,
 220                     int block_start, int block_end);
 221
 222#endif
 223