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 42 enum { 43 SRIOV_NONE, 44 SRIOV_LEGACY, 45 SRIOV_OFFLOADS 46 }; 47 48 enum { 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 68 struct 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 79 struct 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 88 struct mlx5_vport_drop_stats { 89 u64 rx_dropped; 90 u64 tx_dropped; 91 }; 92 93 struct 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 105 struct 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 129 struct 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 148 struct mlx5_eswitch_rep; 149 struct 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 157 struct 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 165 struct 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 */ 177 struct 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 183 struct 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 206 void esw_offloads_cleanup(struct mlx5_eswitch *esw, int nvports); 207 int esw_offloads_init(struct mlx5_eswitch *esw, int nvports); 208 void esw_offloads_cleanup_reps(struct mlx5_eswitch *esw); 209 int esw_offloads_init_reps(struct mlx5_eswitch *esw); 210 211 /* E-Switch API */ 212 int mlx5_eswitch_init(struct mlx5_core_dev *dev); 213 void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw); 214 void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe); 215 int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode); 216 void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw); 217 int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw, 218 int vport, u8 mac[ETH_ALEN]); 219 int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw, 220 int vport, int link_state); 221 int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw, 222 int vport, u16 vlan, u8 qos); 223 int mlx5_eswitch_set_vport_spoofchk(struct mlx5_eswitch *esw, 224 int vport, bool spoofchk); 225 int mlx5_eswitch_set_vport_trust(struct mlx5_eswitch *esw, 226 int vport_num, bool setting); 227 int mlx5_eswitch_set_vport_rate(struct mlx5_eswitch *esw, int vport, 228 u32 max_rate, u32 min_rate); 229 int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw, 230 int vport, struct ifla_vf_info *ivi); 231 int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, 232 int vport, 233 struct ifla_vf_stats *vf_stats); 234 struct mlx5_flow_handle * 235 mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *esw, int vport, 236 u32 sqn); 237 void mlx5_eswitch_del_send_to_vport_rule(struct mlx5_flow_handle *rule); 238 239 struct mlx5_flow_spec; 240 struct mlx5_esw_flow_attr; 241 242 struct mlx5_flow_handle * 243 mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw, 244 struct mlx5_flow_spec *spec, 245 struct mlx5_esw_flow_attr *attr); 246 void 247 mlx5_eswitch_del_offloaded_rule(struct mlx5_eswitch *esw, 248 struct mlx5_flow_handle *rule, 249 struct mlx5_esw_flow_attr *attr); 250 251 struct mlx5_flow_handle * 252 mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, int vport, u32 tirn); 253 254 enum { 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 262 struct 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 274 int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode); 275 int mlx5_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode); 276 int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode); 277 int mlx5_devlink_eswitch_inline_mode_get(struct devlink *devlink, u8 *mode); 278 int mlx5_eswitch_inline_mode_get(struct mlx5_eswitch *esw, int nvfs, u8 *mode); 279 int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, u8 encap); 280 int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap); 281 void 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); 285 void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw, 286 int vport_index, 287 u8 rep_type); 288 void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type); 289 290 int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw, 291 struct mlx5_esw_flow_attr *attr); 292 int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw, 293 struct mlx5_esw_flow_attr *attr); 294 int __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 */ 309 static inline int mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; } 310 static inline void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw) {} 311 static inline void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe) {} 312 static inline int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode) { return 0; } 313 static inline void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw) {} 314 #endif /* CONFIG_MLX5_ESWITCH */ 315 316 #endif /* __MLX5_ESWITCH_H__ */ 317