linux/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h
<<
>>
Prefs
   1/*
   2 * drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h
   3 * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
   4 * Copyright (c) 2017 Jiri Pirko <jiri@mellanox.com>
   5 *
   6 * Redistribution and use in source and binary forms, with or without
   7 * modification, are permitted provided that the following conditions are met:
   8 *
   9 * 1. Redistributions of source code must retain the above copyright
  10 *    notice, this list of conditions and the following disclaimer.
  11 * 2. Redistributions in binary form must reproduce the above copyright
  12 *    notice, this list of conditions and the following disclaimer in the
  13 *    documentation and/or other materials provided with the distribution.
  14 * 3. Neither the names of the copyright holders nor the names of its
  15 *    contributors may be used to endorse or promote products derived from
  16 *    this software without specific prior written permission.
  17 *
  18 * Alternatively, this software may be distributed under the terms of the
  19 * GNU General Public License ("GPL") version 2 as published by the Free
  20 * Software Foundation.
  21 *
  22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32 * POSSIBILITY OF SUCH DAMAGE.
  33 */
  34
  35#ifndef _MLXSW_CORE_ACL_FLEX_KEYS_H
  36#define _MLXSW_CORE_ACL_FLEX_KEYS_H
  37
  38#include <linux/types.h>
  39#include <linux/bitmap.h>
  40
  41#include "item.h"
  42
  43enum mlxsw_afk_element {
  44        MLXSW_AFK_ELEMENT_SRC_SYS_PORT,
  45        MLXSW_AFK_ELEMENT_DMAC,
  46        MLXSW_AFK_ELEMENT_SMAC,
  47        MLXSW_AFK_ELEMENT_ETHERTYPE,
  48        MLXSW_AFK_ELEMENT_IP_PROTO,
  49        MLXSW_AFK_ELEMENT_SRC_IP4,
  50        MLXSW_AFK_ELEMENT_DST_IP4,
  51        MLXSW_AFK_ELEMENT_SRC_IP6_HI,
  52        MLXSW_AFK_ELEMENT_SRC_IP6_LO,
  53        MLXSW_AFK_ELEMENT_DST_IP6_HI,
  54        MLXSW_AFK_ELEMENT_DST_IP6_LO,
  55        MLXSW_AFK_ELEMENT_DST_L4_PORT,
  56        MLXSW_AFK_ELEMENT_SRC_L4_PORT,
  57        MLXSW_AFK_ELEMENT_VID,
  58        MLXSW_AFK_ELEMENT_PCP,
  59        MLXSW_AFK_ELEMENT_TCP_FLAGS,
  60        MLXSW_AFK_ELEMENT_IP_TTL_,
  61        MLXSW_AFK_ELEMENT_IP_ECN,
  62        MLXSW_AFK_ELEMENT_IP_DSCP,
  63        MLXSW_AFK_ELEMENT_MAX,
  64};
  65
  66enum mlxsw_afk_element_type {
  67        MLXSW_AFK_ELEMENT_TYPE_U32,
  68        MLXSW_AFK_ELEMENT_TYPE_BUF,
  69};
  70
  71struct mlxsw_afk_element_info {
  72        enum mlxsw_afk_element element; /* element ID */
  73        enum mlxsw_afk_element_type type;
  74        struct mlxsw_item item; /* element geometry in internal storage */
  75};
  76
  77#define MLXSW_AFK_ELEMENT_INFO(_type, _element, _offset, _shift, _size)         \
  78        [MLXSW_AFK_ELEMENT_##_element] = {                                      \
  79                .element = MLXSW_AFK_ELEMENT_##_element,                        \
  80                .type = _type,                                                  \
  81                .item = {                                                       \
  82                        .offset = _offset,                                      \
  83                        .shift = _shift,                                        \
  84                        .size = {.bits = _size},                                \
  85                        .name = #_element,                                      \
  86                },                                                              \
  87        }
  88
  89#define MLXSW_AFK_ELEMENT_INFO_U32(_element, _offset, _shift, _size)            \
  90        MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_U32,                      \
  91                               _element, _offset, _shift, _size)
  92
  93#define MLXSW_AFK_ELEMENT_INFO_BUF(_element, _offset, _size)                    \
  94        MLXSW_AFK_ELEMENT_INFO(MLXSW_AFK_ELEMENT_TYPE_BUF,                      \
  95                               _element, _offset, 0, _size)
  96
  97/* For the purpose of the driver, define an internal storage scratchpad
  98 * that will be used to store key/mask values. For each defined element type
  99 * define an internal storage geometry.
 100 */
 101static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = {
 102        MLXSW_AFK_ELEMENT_INFO_U32(SRC_SYS_PORT, 0x00, 16, 16),
 103        MLXSW_AFK_ELEMENT_INFO_BUF(DMAC, 0x04, 6),
 104        MLXSW_AFK_ELEMENT_INFO_BUF(SMAC, 0x0A, 6),
 105        MLXSW_AFK_ELEMENT_INFO_U32(ETHERTYPE, 0x00, 0, 16),
 106        MLXSW_AFK_ELEMENT_INFO_U32(IP_PROTO, 0x10, 0, 8),
 107        MLXSW_AFK_ELEMENT_INFO_U32(VID, 0x10, 8, 12),
 108        MLXSW_AFK_ELEMENT_INFO_U32(PCP, 0x10, 20, 3),
 109        MLXSW_AFK_ELEMENT_INFO_U32(TCP_FLAGS, 0x10, 23, 9),
 110        MLXSW_AFK_ELEMENT_INFO_U32(DST_L4_PORT, 0x14, 0, 16),
 111        MLXSW_AFK_ELEMENT_INFO_U32(SRC_L4_PORT, 0x14, 16, 16),
 112        MLXSW_AFK_ELEMENT_INFO_U32(IP_TTL_, 0x18, 0, 8),
 113        MLXSW_AFK_ELEMENT_INFO_U32(IP_ECN, 0x18, 9, 2),
 114        MLXSW_AFK_ELEMENT_INFO_U32(IP_DSCP, 0x18, 11, 6),
 115        MLXSW_AFK_ELEMENT_INFO_U32(SRC_IP4, 0x20, 0, 32),
 116        MLXSW_AFK_ELEMENT_INFO_U32(DST_IP4, 0x24, 0, 32),
 117        MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP6_HI, 0x20, 8),
 118        MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP6_LO, 0x28, 8),
 119        MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP6_HI, 0x30, 8),
 120        MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP6_LO, 0x38, 8),
 121};
 122
 123#define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x40
 124
 125struct mlxsw_afk_element_inst { /* element instance in actual block */
 126        const struct mlxsw_afk_element_info *info;
 127        enum mlxsw_afk_element_type type;
 128        struct mlxsw_item item; /* element geometry in block */
 129};
 130
 131#define MLXSW_AFK_ELEMENT_INST(_type, _element, _offset, _shift, _size)         \
 132        {                                                                       \
 133                .info = &mlxsw_afk_element_infos[MLXSW_AFK_ELEMENT_##_element], \
 134                .type = _type,                                                  \
 135                .item = {                                                       \
 136                        .offset = _offset,                                      \
 137                        .shift = _shift,                                        \
 138                        .size = {.bits = _size},                                \
 139                        .name = #_element,                                      \
 140                },                                                              \
 141        }
 142
 143#define MLXSW_AFK_ELEMENT_INST_U32(_element, _offset, _shift, _size)            \
 144        MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_U32,                      \
 145                               _element, _offset, _shift, _size)
 146
 147#define MLXSW_AFK_ELEMENT_INST_BUF(_element, _offset, _size)                    \
 148        MLXSW_AFK_ELEMENT_INST(MLXSW_AFK_ELEMENT_TYPE_BUF,                      \
 149                               _element, _offset, 0, _size)
 150
 151struct mlxsw_afk_block {
 152        u16 encoding; /* block ID */
 153        struct mlxsw_afk_element_inst *instances;
 154        unsigned int instances_count;
 155};
 156
 157#define MLXSW_AFK_BLOCK(_encoding, _instances)                                  \
 158        {                                                                       \
 159                .encoding = _encoding,                                          \
 160                .instances = _instances,                                        \
 161                .instances_count = ARRAY_SIZE(_instances),                      \
 162        }
 163
 164struct mlxsw_afk_element_usage {
 165        DECLARE_BITMAP(usage, MLXSW_AFK_ELEMENT_MAX);
 166};
 167
 168#define mlxsw_afk_element_usage_for_each(element, elusage)                      \
 169        for_each_set_bit(element, (elusage)->usage, MLXSW_AFK_ELEMENT_MAX)
 170
 171static inline void
 172mlxsw_afk_element_usage_add(struct mlxsw_afk_element_usage *elusage,
 173                            enum mlxsw_afk_element element)
 174{
 175        __set_bit(element, elusage->usage);
 176}
 177
 178static inline void
 179mlxsw_afk_element_usage_zero(struct mlxsw_afk_element_usage *elusage)
 180{
 181        bitmap_zero(elusage->usage, MLXSW_AFK_ELEMENT_MAX);
 182}
 183
 184static inline void
 185mlxsw_afk_element_usage_fill(struct mlxsw_afk_element_usage *elusage,
 186                             const enum mlxsw_afk_element *elements,
 187                             unsigned int elements_count)
 188{
 189        int i;
 190
 191        mlxsw_afk_element_usage_zero(elusage);
 192        for (i = 0; i < elements_count; i++)
 193                mlxsw_afk_element_usage_add(elusage, elements[i]);
 194}
 195
 196static inline bool
 197mlxsw_afk_element_usage_subset(struct mlxsw_afk_element_usage *elusage_small,
 198                               struct mlxsw_afk_element_usage *elusage_big)
 199{
 200        int i;
 201
 202        for (i = 0; i < MLXSW_AFK_ELEMENT_MAX; i++)
 203                if (test_bit(i, elusage_small->usage) &&
 204                    !test_bit(i, elusage_big->usage))
 205                        return false;
 206        return true;
 207}
 208
 209struct mlxsw_afk;
 210
 211struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks,
 212                                   const struct mlxsw_afk_block *blocks,
 213                                   unsigned int blocks_count);
 214void mlxsw_afk_destroy(struct mlxsw_afk *mlxsw_afk);
 215
 216struct mlxsw_afk_key_info;
 217
 218struct mlxsw_afk_key_info *
 219mlxsw_afk_key_info_get(struct mlxsw_afk *mlxsw_afk,
 220                       struct mlxsw_afk_element_usage *elusage);
 221void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info);
 222bool mlxsw_afk_key_info_subset(struct mlxsw_afk_key_info *key_info,
 223                               struct mlxsw_afk_element_usage *elusage);
 224
 225u16
 226mlxsw_afk_key_info_block_encoding_get(const struct mlxsw_afk_key_info *key_info,
 227                                      int block_index);
 228unsigned int
 229mlxsw_afk_key_info_blocks_count_get(const struct mlxsw_afk_key_info *key_info);
 230
 231struct mlxsw_afk_element_values {
 232        struct mlxsw_afk_element_usage elusage;
 233        struct {
 234                char key[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
 235                char mask[MLXSW_AFK_ELEMENT_STORAGE_SIZE];
 236        } storage;
 237};
 238
 239void mlxsw_afk_values_add_u32(struct mlxsw_afk_element_values *values,
 240                              enum mlxsw_afk_element element,
 241                              u32 key_value, u32 mask_value);
 242void mlxsw_afk_values_add_buf(struct mlxsw_afk_element_values *values,
 243                              enum mlxsw_afk_element element,
 244                              const char *key_value, const char *mask_value,
 245                              unsigned int len);
 246void mlxsw_afk_encode(struct mlxsw_afk_key_info *key_info,
 247                      struct mlxsw_afk_element_values *values,
 248                      char *key, char *mask);
 249
 250#endif
 251