linux/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2015, Mellanox Technologies, Ltd.  All rights reserved.
   3 *
   4 * This software is available to you under a choice of one of two
   5 * licenses.  You may choose to be licensed under the terms of the GNU
   6 * General Public License (GPL) Version 2, available from the file
   7 * COPYING in the main directory of this source tree, or the
   8 * OpenIB.org BSD license below:
   9 *
  10 *     Redistribution and use in source and binary forms, with or
  11 *     without modification, are permitted provided that the following
  12 *     conditions are met:
  13 *
  14 *      - Redistributions of source code must retain the above
  15 *        copyright notice, this list of conditions and the following
  16 *        disclaimer.
  17 *
  18 *      - Redistributions in binary form must reproduce the above
  19 *        copyright notice, this list of conditions and the following
  20 *        disclaimer in the documentation and/or other materials
  21 *        provided with the distribution.
  22 *
  23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30 * SOFTWARE.
  31 */
  32
  33#ifndef __MLX5_ESWITCH_H__
  34#define __MLX5_ESWITCH_H__
  35
  36#include <linux/if_ether.h>
  37#include <linux/if_link.h>
  38#include <net/devlink.h>
  39#include <linux/mlx5/device.h>
  40#include "lib/mpfs.h"
  41
  42enum {
  43        SRIOV_NONE,
  44        SRIOV_LEGACY,
  45        SRIOV_OFFLOADS
  46};
  47
  48enum {
  49        REP_ETH,
  50        NUM_REP_TYPES,
  51};
  52
  53#ifdef CONFIG_MLX5_ESWITCH
  54
  55#define MLX5_MAX_UC_PER_VPORT(dev) \
  56        (1 << MLX5_CAP_GEN(dev, log_max_current_uc_list))
  57
  58#define MLX5_MAX_MC_PER_VPORT(dev) \
  59        (1 << MLX5_CAP_GEN(dev, log_max_current_mc_list))
  60
  61#define FDB_UPLINK_VPORT 0xffff
  62
  63#define MLX5_MIN_BW_SHARE 1
  64
  65#define MLX5_RATE_TO_BW_SHARE(rate, divider, limit) \
  66        min_t(u32, max_t(u32, (rate) / (divider), MLX5_MIN_BW_SHARE), limit)
  67
  68struct vport_ingress {
  69        struct mlx5_flow_table *acl;
  70        struct mlx5_flow_group *allow_untagged_spoofchk_grp;
  71        struct mlx5_flow_group *allow_spoofchk_only_grp;
  72        struct mlx5_flow_group *allow_untagged_only_grp;
  73        struct mlx5_flow_group *drop_grp;
  74        struct mlx5_flow_handle  *allow_rule;
  75        struct mlx5_flow_handle  *drop_rule;
  76        struct mlx5_fc           *drop_counter;
  77};
  78
  79struct vport_egress {
  80        struct mlx5_flow_table *acl;
  81        struct mlx5_flow_group *allowed_vlans_grp;
  82        struct mlx5_flow_group *drop_grp;
  83        struct mlx5_flow_handle  *allowed_vlan;
  84        struct mlx5_flow_handle  *drop_rule;
  85        struct mlx5_fc           *drop_counter;
  86};
  87
  88struct mlx5_vport_drop_stats {
  89        u64 rx_dropped;
  90        u64 tx_dropped;
  91};
  92
  93struct mlx5_vport_info {
  94        u8                      mac[ETH_ALEN];
  95        u16                     vlan;
  96        u8                      qos;
  97        u64                     node_guid;
  98        int                     link_state;
  99        u32                     min_rate;
 100        u32                     max_rate;
 101        bool                    spoofchk;
 102        bool                    trusted;
 103};
 104
 105struct mlx5_vport {
 106        struct mlx5_core_dev    *dev;
 107        int                     vport;
 108        struct hlist_head       uc_list[MLX5_L2_ADDR_HASH_SIZE];
 109        struct hlist_head       mc_list[MLX5_L2_ADDR_HASH_SIZE];
 110        struct mlx5_flow_handle *promisc_rule;
 111        struct mlx5_flow_handle *allmulti_rule;
 112        struct work_struct      vport_change_handler;
 113
 114        struct vport_ingress    ingress;
 115        struct vport_egress     egress;
 116
 117        struct mlx5_vport_info  info;
 118
 119        struct {
 120                bool            enabled;
 121                u32             esw_tsar_ix;
 122                u32             bw_share;
 123        } qos;
 124
 125        bool                    enabled;
 126        u16                     enabled_events;
 127};
 128
 129struct mlx5_eswitch_fdb {
 130        void *fdb;
 131        union {
 132                struct legacy_fdb {
 133                        struct mlx5_flow_group *addr_grp;
 134                        struct mlx5_flow_group *allmulti_grp;
 135                        struct mlx5_flow_group *promisc_grp;
 136                } legacy;
 137
 138                struct offloads_fdb {
 139                        struct mlx5_flow_table *fdb;
 140                        struct mlx5_flow_group *send_to_vport_grp;
 141                        struct mlx5_flow_group *miss_grp;
 142                        struct mlx5_flow_handle *miss_rule;
 143                        int vlan_push_pop_refcount;
 144                } offloads;
 145        };
 146};
 147
 148struct mlx5_eswitch_rep;
 149struct mlx5_eswitch_rep_if {
 150        int                    (*load)(struct mlx5_core_dev *dev,
 151                                       struct mlx5_eswitch_rep *rep);
 152        void                   (*unload)(struct mlx5_eswitch_rep *rep);
 153        void                    *priv;
 154        bool                   valid;
 155};
 156
 157struct mlx5_eswitch_rep {
 158        struct mlx5_eswitch_rep_if rep_if[NUM_REP_TYPES];
 159        u16                    vport;
 160        u8                     hw_id[ETH_ALEN];
 161        u16                    vlan;
 162        u32                    vlan_refcount;
 163};
 164
 165struct mlx5_esw_offload {
 166        struct mlx5_flow_table *ft_offloads;
 167        struct mlx5_flow_group *vport_rx_group;
 168        struct mlx5_eswitch_rep *vport_reps;
 169        DECLARE_HASHTABLE(encap_tbl, 8);
 170        DECLARE_HASHTABLE(mod_hdr_tbl, 8);
 171        u8 inline_mode;
 172        u64 num_flows;
 173        u8 encap;
 174};
 175
 176/* E-Switch MC FDB table hash node */
 177struct esw_mc_addr { /* SRIOV only */
 178        struct l2addr_node     node;
 179        struct mlx5_flow_handle *uplink_rule; /* Forward to uplink rule */
 180        u32                    refcnt;
 181};
 182
 183struct mlx5_eswitch {
 184        struct mlx5_core_dev    *dev;
 185        struct mlx5_eswitch_fdb fdb_table;
 186        struct hlist_head       mc_table[MLX5_L2_ADDR_HASH_SIZE];
 187        struct workqueue_struct *work_queue;
 188        struct mlx5_vport       *vports;
 189        int                     total_vports;
 190        int                     enabled_vports;
 191        /* Synchronize between vport change events
 192         * and async SRIOV admin state changes
 193         */
 194        struct mutex            state_lock;
 195        struct esw_mc_addr      mc_promisc;
 196
 197        struct {
 198                bool            enabled;
 199                u32             root_tsar_id;
 200        } qos;
 201
 202        struct mlx5_esw_offload offloads;
 203        int                     mode;
 204};
 205
 206void esw_offloads_cleanup(struct mlx5_eswitch *esw, int nvports);
 207int esw_offloads_init(struct mlx5_eswitch *esw, int nvports);
 208void esw_offloads_cleanup_reps(struct mlx5_eswitch *esw);
 209int esw_offloads_init_reps(struct mlx5_eswitch *esw);
 210
 211/* E-Switch API */
 212int mlx5_eswitch_init(struct mlx5_core_dev *dev);
 213void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw);
 214void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe);
 215int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode);
 216void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw);
 217int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
 218                               int vport, u8 mac[ETH_ALEN]);
 219int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
 220                                 int vport, int link_state);
 221int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
 222                                int vport, u16 vlan, u8 qos);
 223int mlx5_eswitch_set_vport_spoofchk(struct mlx5_eswitch *esw,
 224                                    int vport, bool spoofchk);
 225int mlx5_eswitch_set_vport_trust(struct mlx5_eswitch *esw,
 226                                 int vport_num, bool setting);
 227int mlx5_eswitch_set_vport_rate(struct mlx5_eswitch *esw, int vport,
 228                                u32 max_rate, u32 min_rate);
 229int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw,
 230                                  int vport, struct ifla_vf_info *ivi);
 231int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw,
 232                                 int vport,
 233                                 struct ifla_vf_stats *vf_stats);
 234struct mlx5_flow_handle *
 235mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *esw, int vport,
 236                                    u32 sqn);
 237void mlx5_eswitch_del_send_to_vport_rule(struct mlx5_flow_handle *rule);
 238
 239struct mlx5_flow_spec;
 240struct mlx5_esw_flow_attr;
 241
 242struct mlx5_flow_handle *
 243mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
 244                                struct mlx5_flow_spec *spec,
 245                                struct mlx5_esw_flow_attr *attr);
 246void
 247mlx5_eswitch_del_offloaded_rule(struct mlx5_eswitch *esw,
 248                                struct mlx5_flow_handle *rule,
 249                                struct mlx5_esw_flow_attr *attr);
 250
 251struct mlx5_flow_handle *
 252mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, int vport, u32 tirn);
 253
 254enum {
 255        SET_VLAN_STRIP  = BIT(0),
 256        SET_VLAN_INSERT = BIT(1)
 257};
 258
 259#define MLX5_FLOW_CONTEXT_ACTION_VLAN_POP  0x4000
 260#define MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH 0x8000
 261
 262struct mlx5_esw_flow_attr {
 263        struct mlx5_eswitch_rep *in_rep;
 264        struct mlx5_eswitch_rep *out_rep;
 265
 266        int     action;
 267        u16     vlan;
 268        bool    vlan_handled;
 269        u32     encap_id;
 270        u32     mod_hdr_id;
 271        struct mlx5e_tc_flow_parse_attr *parse_attr;
 272};
 273
 274int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode);
 275int mlx5_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode);
 276int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode);
 277int mlx5_devlink_eswitch_inline_mode_get(struct devlink *devlink, u8 *mode);
 278int mlx5_eswitch_inline_mode_get(struct mlx5_eswitch *esw, int nvfs, u8 *mode);
 279int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, u8 encap);
 280int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap);
 281void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw,
 282                                     int vport_index,
 283                                     struct mlx5_eswitch_rep_if *rep_if,
 284                                     u8 rep_type);
 285void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw,
 286                                       int vport_index,
 287                                       u8 rep_type);
 288void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type);
 289
 290int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw,
 291                                 struct mlx5_esw_flow_attr *attr);
 292int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw,
 293                                 struct mlx5_esw_flow_attr *attr);
 294int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
 295                                  int vport, u16 vlan, u8 qos, u8 set_flags);
 296
 297#define MLX5_DEBUG_ESWITCH_MASK BIT(3)
 298
 299#define esw_info(dev, format, ...)                              \
 300        pr_info("(%s): E-Switch: " format, (dev)->priv.name, ##__VA_ARGS__)
 301
 302#define esw_warn(dev, format, ...)                              \
 303        pr_warn("(%s): E-Switch: " format, (dev)->priv.name, ##__VA_ARGS__)
 304
 305#define esw_debug(dev, format, ...)                             \
 306        mlx5_core_dbg_mask(dev, MLX5_DEBUG_ESWITCH_MASK, format, ##__VA_ARGS__)
 307#else  /* CONFIG_MLX5_ESWITCH */
 308/* eswitch API stubs */
 309static inline int  mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; }
 310static inline void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw) {}
 311static inline void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe) {}
 312static inline int  mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode) { return 0; }
 313static inline void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw) {}
 314#endif /* CONFIG_MLX5_ESWITCH */
 315
 316#endif /* __MLX5_ESWITCH_H__ */
 317