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/* 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 */
  76static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = {
  77        MLXSW_AFK_ELEMENT_INFO_U32(SRC_SYS_PORT, 0x00, 16, 8),
  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
 106struct 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};
 111
 112#define MLXSW_AFK_ELEMENT_INST(_type, _element, _offset, _shift, _size)         \
 113        {                                                                       \
 114                .info = &mlxsw_afk_element_infos[MLXSW_AFK_ELEMENT_##_element], \
 115                .type = _type,                                                  \
 116                .item = {                                                       \
 117                        .offset = _offset,                                      \
 118                        .shift = _shift,                                        \
 119                        .size = {.bits = _size},                                \
 120                        .name = #_element,                                      \
 121                },                                                              \
 122        }
 123
 124#define MLXSW_AFK_ELEMENT_INST_U32(_element, _offset, _shift, _size)            \
 125        MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32,                      \
 126                               _element, _offset, _shift, _size)
 127
 128#define MLXSW_AFK_ELEMENT_INST_BUF(_element, _offset, _size)                    \
 129        MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_BUF,                      \
 130                               _element, _offset, 0, _size)
 131
 132struct mlxsw_afk_block {
 133        u16 encoding; /* block ID */
 134        struct mlxsw_afk_element_inst *instances;
 135        unsigned int instances_count;
 136};
 137
 138#define MLXSW_AFK_BLOCK(_encoding, _instances)                                  \
 139        {                                                                       \
 140                .encoding = _encoding,                                          \
 141                .instances = _instances,                                        \
 142                .instances_count = ARRAY_SIZE(_instances),                      \
 143        }
 144
 145struct mlxsw_afk_element_usage {
 146        DECLARE_BITMAP(usage, MLXSW_AFK_ELEMENT_MAX);
 147};
 148
 149#define mlxsw_afk_element_usage_for_each(element, elusage)                      \
 150        for_each_set_bit(element, (elusage)->usage, MLXSW_AFK_ELEMENT_MAX)
 151
 152static inline void
 153mlxsw_afk_element_usage_add(struct mlxsw_afk_element_usage *elusage,
 154                            enum mlxsw_afk_element element)
 155{
 156        __set_bit(element, elusage->usage);
 157}
 158
 159static inline void
 160mlxsw_afk_element_usage_zero(struct mlxsw_afk_element_usage *elusage)
 161{
 162        bitmap_zero(elusage->usage, MLXSW_AFK_ELEMENT_MAX);
 163}
 164
 165static inline void
 166mlxsw_afk_element_usage_fill(struct mlxsw_afk_element_usage *elusage,
 167                             const enum mlxsw_afk_element *elements,
 168                             unsigned int elements_count)
 169{
 170        int i;
 171
 172        mlxsw_afk_element_usage_zero(elusage);
 173        for (i = 0; i < elements_count; i++)
 174                mlxsw_afk_element_usage_add(elusage, elements[i]);
 175}
 176
 177static inline bool
 178mlxsw_afk_element_usage_subset(struct mlxsw_afk_element_usage *elusage_small,
 179                               struct mlxsw_afk_element_usage *elusage_big)
 180{
 181        int i;
 182
 183        for (i = 0; i < MLXSW_AFK_ELEMENT_MAX; i++)
 184                if (test_bit(i, elusage_small->usage) &&
 185                    !test_bit(i, elusage_big->usage))
 186                        return false;
 187        return true;
 188}
 189
 190struct mlxsw_afk;
 191
 192struct mlxsw_afk_ops {
 193        const struct mlxsw_afk_block *blocks;
 194        unsigned int blocks_count;
 195        void (*encode_block)(char *output, int block_index, char *block);
 196        void (*clear_block)(char *output, int block_index);
 197};
 198
 199struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
 200                                   const struct mlxsw_afk_ops *ops);
 201void mlxsw_afk_destroy(struct mlxsw_afk *mlxsw_afk);
 202
 203struct mlxsw_afk_key_info;
 204
 205struct mlxsw_afk_key_info *
 206mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk,
 207                       struct mlxsw_afk_element_usage *elusage);
 208void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info);
 209bool mlxsw_afk_key_info_subset(struct mlxsw_afk_key_info *key_info,
 210                               struct mlxsw_afk_element_usage *elusage);
 211
 212u16
 213mlxsw_afk_key_info_block_encoding_get(const struct mlxsw_afk_key_info *key_info,
 214                                      int block_index);
 215unsigned int
 216mlxsw_afk_key_info_blocks_count_get(const struct mlxsw_afk_key_info *key_info);
 217
 218struct mlxsw_afk_element_values {
 219        struct mlxsw_afk_element_usage elusage;
 220        struct {
 221                char key[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
 222                char mask[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
 223        } storage;
 224};
 225
 226void mlxsw_afk_values_add_u32(struct mlxsw_afk_element_values *values,
 227                              enum mlxsw_afk_element element,
 228                              u32 key_value, u32 mask_value);
 229void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values,
 230                              enum mlxsw_afk_element element,
 231                              const char *key_value, const char *mask_value,
 232                              unsigned int len);
 233void mlxsw_afk_encode(struct mlxsw_afk *mlxsw_afk,
 234                      struct mlxsw_afk_key_info *key_info,
 235                      struct mlxsw_afk_element_values *values,
 236                      char *key, char *mask);
 237void mlxsw_afk_clear(struct mlxsw_afk *mlxsw_afk, char *key,
 238                     int block_start, int block_end);
 239
 240#endif
 241