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_MAX,
  37};
  38
  39enum mlxsw_afk_element_type {
  40        MLXSW_AFK_ELEMENT_TYPE_U32,
  41        MLXSW_AFK_ELEMENT_TYPE_BUF,
  42};
  43
  44struct mlxsw_afk_element_info {
  45        enum mlxsw_afk_element element; /* element ID */
  46        enum mlxsw_afk_element_type type;
  47        struct mlxsw_item item; /* element geometry in internal storage */
  48};
  49
  50#define MLXSW_AFK_ELEMENT_INFO(_type, _element, _offset, _shift, _size)         \
  51        [MLXSW_AFK_ELEMENT_##_element] = {                                      \
  52                .element = MLXSW_AFK_ELEMENT_##_element,                        \
  53                .type = _type,                                                  \
  54                .item = {                                                       \
  55                        .offset = _offset,                                      \
  56                        .shift = _shift,                                        \
  57                        .size = {.bits = _size},                                \
  58                        .name = #_element,                                      \
  59                },                                                              \
  60        }
  61
  62#define MLXSW_AFK_ELEMENT_INFO_U32(_element, _offset, _shift, _size)            \
  63        MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_U32,                      \
  64                               _element, _offset, _shift, _size)
  65
  66#define MLXSW_AFK_ELEMENT_INFO_BUF(_element, _offset, _size)                    \
  67        MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_BUF,                      \
  68                               _element, _offset, 0, _size)
  69
  70/* For the purpose of the driver, define an internal storage scratchpad
  71 * that will be used to store key/mask values. For each defined element type
  72 * define an internal storage geometry.
  73 */
  74static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = {
  75        MLXSW_AFK_ELEMENT_INFO_U32(SRC_SYS_PORT, 0x00, 16, 8),
  76        MLXSW_AFK_ELEMENT_INFO_BUF(DMAC_32_47, 0x04, 2),
  77        MLXSW_AFK_ELEMENT_INFO_BUF(DMAC_0_31, 0x06, 4),
  78        MLXSW_AFK_ELEMENT_INFO_BUF(SMAC_32_47, 0x0A, 2),
  79        MLXSW_AFK_ELEMENT_INFO_BUF(SMAC_0_31, 0x0C, 4),
  80        MLXSW_AFK_ELEMENT_INFO_U32(ETHERTYPE, 0x00, 0, 16),
  81        MLXSW_AFK_ELEMENT_INFO_U32(IP_PROTO, 0x10, 0, 8),
  82        MLXSW_AFK_ELEMENT_INFO_U32(VID, 0x10, 8, 12),
  83        MLXSW_AFK_ELEMENT_INFO_U32(PCP, 0x10, 20, 3),
  84        MLXSW_AFK_ELEMENT_INFO_U32(TCP_FLAGS, 0x10, 23, 9),
  85        MLXSW_AFK_ELEMENT_INFO_U32(DST_L4_PORT, 0x14, 0, 16),
  86        MLXSW_AFK_ELEMENT_INFO_U32(SRC_L4_PORT, 0x14, 16, 16),
  87        MLXSW_AFK_ELEMENT_INFO_U32(IP_TTL_, 0x18, 0, 8),
  88        MLXSW_AFK_ELEMENT_INFO_U32(IP_ECN, 0x18, 9, 2),
  89        MLXSW_AFK_ELEMENT_INFO_U32(IP_DSCP, 0x18, 11, 6),
  90        MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_96_127, 0x20, 4),
  91        MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_64_95, 0x24, 4),
  92        MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_32_63, 0x28, 4),
  93        MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_0_31, 0x2C, 4),
  94        MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_96_127, 0x30, 4),
  95        MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_64_95, 0x34, 4),
  96        MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_32_63, 0x38, 4),
  97        MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_0_31, 0x3C, 4),
  98};
  99
 100#define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x40
 101
 102struct mlxsw_afk_element_inst { /* element instance in actual block */
 103        const struct mlxsw_afk_element_info *info;
 104        enum mlxsw_afk_element_type type;
 105        struct mlxsw_item item; /* element geometry in block */
 106};
 107
 108#define MLXSW_AFK_ELEMENT_INST(_type, _element, _offset, _shift, _size)         \
 109        {                                                                       \
 110                .info = &mlxsw_afk_element_infos[MLXSW_AFK_ELEMENT_##_element], \
 111                .type = _type,                                                  \
 112                .item = {                                                       \
 113                        .offset = _offset,                                      \
 114                        .shift = _shift,                                        \
 115                        .size = {.bits = _size},                                \
 116                        .name = #_element,                                      \
 117                },                                                              \
 118        }
 119
 120#define MLXSW_AFK_ELEMENT_INST_U32(_element, _offset, _shift, _size)            \
 121        MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32,                      \
 122                               _element, _offset, _shift, _size)
 123
 124#define MLXSW_AFK_ELEMENT_INST_BUF(_element, _offset, _size)                    \
 125        MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_BUF,                      \
 126                               _element, _offset, 0, _size)
 127
 128struct mlxsw_afk_block {
 129        u16 encoding; /* block ID */
 130        struct mlxsw_afk_element_inst *instances;
 131        unsigned int instances_count;
 132};
 133
 134#define MLXSW_AFK_BLOCK(_encoding, _instances)                                  \
 135        {                                                                       \
 136                .encoding = _encoding,                                          \
 137                .instances = _instances,                                        \
 138                .instances_count = ARRAY_SIZE(_instances),                      \
 139        }
 140
 141struct mlxsw_afk_element_usage {
 142        DECLARE_BITMAP(usage, MLXSW_AFK_ELEMENT_MAX);
 143};
 144
 145#define mlxsw_afk_element_usage_for_each(element, elusage)                      \
 146        for_each_set_bit(element, (elusage)->usage, MLXSW_AFK_ELEMENT_MAX)
 147
 148static inline void
 149mlxsw_afk_element_usage_add(struct mlxsw_afk_element_usage *elusage,
 150                            enum mlxsw_afk_element element)
 151{
 152        __set_bit(element, elusage->usage);
 153}
 154
 155static inline void
 156mlxsw_afk_element_usage_zero(struct mlxsw_afk_element_usage *elusage)
 157{
 158        bitmap_zero(elusage->usage, MLXSW_AFK_ELEMENT_MAX);
 159}
 160
 161static inline void
 162mlxsw_afk_element_usage_fill(struct mlxsw_afk_element_usage *elusage,
 163                             const enum mlxsw_afk_element *elements,
 164                             unsigned int elements_count)
 165{
 166        int i;
 167
 168        mlxsw_afk_element_usage_zero(elusage);
 169        for (i = 0; i < elements_count; i++)
 170                mlxsw_afk_element_usage_add(elusage, elements[i]);
 171}
 172
 173static inline bool
 174mlxsw_afk_element_usage_subset(struct mlxsw_afk_element_usage *elusage_small,
 175                               struct mlxsw_afk_element_usage *elusage_big)
 176{
 177        int i;
 178
 179        for (i = 0; i < MLXSW_AFK_ELEMENT_MAX; i++)
 180                if (test_bit(i, elusage_small->usage) &&
 181                    !test_bit(i, elusage_big->usage))
 182                        return false;
 183        return true;
 184}
 185
 186struct mlxsw_afk;
 187
 188struct mlxsw_afk_ops {
 189        const struct mlxsw_afk_block *blocks;
 190        unsigned int blocks_count;
 191        void (*encode_block)(char *block, int block_index, char *output);
 192};
 193
 194struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
 195                                   const struct mlxsw_afk_ops *ops);
 196void mlxsw_afk_destroy(struct mlxsw_afk *mlxsw_afk);
 197
 198struct mlxsw_afk_key_info;
 199
 200struct mlxsw_afk_key_info *
 201mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk,
 202                       struct mlxsw_afk_element_usage *elusage);
 203void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info);
 204bool mlxsw_afk_key_info_subset(struct mlxsw_afk_key_info *key_info,
 205                               struct mlxsw_afk_element_usage *elusage);
 206
 207u16
 208mlxsw_afk_key_info_block_encoding_get(const struct mlxsw_afk_key_info *key_info,
 209                                      int block_index);
 210unsigned int
 211mlxsw_afk_key_info_blocks_count_get(const struct mlxsw_afk_key_info *key_info);
 212
 213struct mlxsw_afk_element_values {
 214        struct mlxsw_afk_element_usage elusage;
 215        struct {
 216                char key[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
 217                char mask[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
 218        } storage;
 219};
 220
 221void mlxsw_afk_values_add_u32(struct mlxsw_afk_element_values *values,
 222                              enum mlxsw_afk_element element,
 223                              u32 key_value, u32 mask_value);
 224void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values,
 225                              enum mlxsw_afk_element element,
 226                              const char *key_value, const char *mask_value,
 227                              unsigned int len);
 228void mlxsw_afk_encode(struct mlxsw_afk *mlxsw_afk,
 229                      struct mlxsw_afk_key_info *key_info,
 230                      struct mlxsw_afk_element_values *values,
 231                      char *key, char *mask, int block_start, int block_end);
 232
 233#endif
 234