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 #ifdef CONFIG_MLX5_ESWITCH 49 50 #define MLX5_MAX_UC_PER_VPORT(dev) \ 51 (1 << MLX5_CAP_GEN(dev, log_max_current_uc_list)) 52 53 #define MLX5_MAX_MC_PER_VPORT(dev) \ 54 (1 << MLX5_CAP_GEN(dev, log_max_current_mc_list)) 55 56 #define FDB_UPLINK_VPORT 0xffff 57 58 #define MLX5_MIN_BW_SHARE 1 59 60 #define MLX5_RATE_TO_BW_SHARE(rate, divider, limit) \ 61 min_t(u32, max_t(u32, (rate) / (divider), MLX5_MIN_BW_SHARE), limit) 62 63 struct vport_ingress { 64 struct mlx5_flow_table *acl; 65 struct mlx5_flow_group *allow_untagged_spoofchk_grp; 66 struct mlx5_flow_group *allow_spoofchk_only_grp; 67 struct mlx5_flow_group *allow_untagged_only_grp; 68 struct mlx5_flow_group *drop_grp; 69 struct mlx5_flow_handle *allow_rule; 70 struct mlx5_flow_handle *drop_rule; 71 }; 72 73 struct vport_egress { 74 struct mlx5_flow_table *acl; 75 struct mlx5_flow_group *allowed_vlans_grp; 76 struct mlx5_flow_group *drop_grp; 77 struct mlx5_flow_handle *allowed_vlan; 78 struct mlx5_flow_handle *drop_rule; 79 }; 80 81 struct mlx5_vport_info { 82 u8 mac[ETH_ALEN]; 83 u16 vlan; 84 u8 qos; 85 u64 node_guid; 86 int link_state; 87 u32 min_rate; 88 u32 max_rate; 89 bool spoofchk; 90 bool trusted; 91 }; 92 93 struct mlx5_vport { 94 struct mlx5_core_dev *dev; 95 int vport; 96 struct hlist_head uc_list[MLX5_L2_ADDR_HASH_SIZE]; 97 struct hlist_head mc_list[MLX5_L2_ADDR_HASH_SIZE]; 98 struct mlx5_flow_handle *promisc_rule; 99 struct mlx5_flow_handle *allmulti_rule; 100 struct work_struct vport_change_handler; 101 102 struct vport_ingress ingress; 103 struct vport_egress egress; 104 105 struct mlx5_vport_info info; 106 107 struct { 108 bool enabled; 109 u32 esw_tsar_ix; 110 u32 bw_share; 111 } qos; 112 113 bool enabled; 114 u16 enabled_events; 115 }; 116 117 struct mlx5_eswitch_fdb { 118 void *fdb; 119 union { 120 struct legacy_fdb { 121 struct mlx5_flow_group *addr_grp; 122 struct mlx5_flow_group *allmulti_grp; 123 struct mlx5_flow_group *promisc_grp; 124 } legacy; 125 126 struct offloads_fdb { 127 struct mlx5_flow_table *fdb; 128 struct mlx5_flow_group *send_to_vport_grp; 129 struct mlx5_flow_group *miss_grp; 130 struct mlx5_flow_handle *miss_rule; 131 int vlan_push_pop_refcount; 132 } offloads; 133 }; 134 }; 135 136 struct mlx5_esw_sq { 137 struct mlx5_flow_handle *send_to_vport_rule; 138 struct list_head list; 139 }; 140 141 struct mlx5_eswitch_rep { 142 int (*load)(struct mlx5_eswitch *esw, 143 struct mlx5_eswitch_rep *rep); 144 void (*unload)(struct mlx5_eswitch *esw, 145 struct mlx5_eswitch_rep *rep); 146 u16 vport; 147 u8 hw_id[ETH_ALEN]; 148 struct net_device *netdev; 149 150 struct mlx5_flow_handle *vport_rx_rule; 151 struct list_head vport_sqs_list; 152 u16 vlan; 153 u32 vlan_refcount; 154 bool valid; 155 }; 156 157 struct mlx5_esw_offload { 158 struct mlx5_flow_table *ft_offloads; 159 struct mlx5_flow_group *vport_rx_group; 160 struct mlx5_eswitch_rep *vport_reps; 161 DECLARE_HASHTABLE(encap_tbl, 8); 162 DECLARE_HASHTABLE(mod_hdr_tbl, 8); 163 u8 inline_mode; 164 u64 num_flows; 165 u8 encap; 166 }; 167 168 /* E-Switch MC FDB table hash node */ 169 struct esw_mc_addr { /* SRIOV only */ 170 struct l2addr_node node; 171 struct mlx5_flow_handle *uplink_rule; /* Forward to uplink rule */ 172 u32 refcnt; 173 }; 174 175 struct mlx5_eswitch { 176 struct mlx5_core_dev *dev; 177 struct mlx5_eswitch_fdb fdb_table; 178 struct hlist_head mc_table[MLX5_L2_ADDR_HASH_SIZE]; 179 struct workqueue_struct *work_queue; 180 struct mlx5_vport *vports; 181 int total_vports; 182 int enabled_vports; 183 /* Synchronize between vport change events 184 * and async SRIOV admin state changes 185 */ 186 struct mutex state_lock; 187 struct esw_mc_addr mc_promisc; 188 189 struct { 190 bool enabled; 191 u32 root_tsar_id; 192 } qos; 193 194 struct mlx5_esw_offload offloads; 195 int mode; 196 }; 197 198 void esw_offloads_cleanup(struct mlx5_eswitch *esw, int nvports); 199 int esw_offloads_init(struct mlx5_eswitch *esw, int nvports); 200 201 /* E-Switch API */ 202 int mlx5_eswitch_init(struct mlx5_core_dev *dev); 203 void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw); 204 void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe); 205 int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode); 206 void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw); 207 int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw, 208 int vport, u8 mac[ETH_ALEN]); 209 int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw, 210 int vport, int link_state); 211 int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw, 212 int vport, u16 vlan, u8 qos); 213 int mlx5_eswitch_set_vport_spoofchk(struct mlx5_eswitch *esw, 214 int vport, bool spoofchk); 215 int mlx5_eswitch_set_vport_trust(struct mlx5_eswitch *esw, 216 int vport_num, bool setting); 217 int mlx5_eswitch_set_vport_rate(struct mlx5_eswitch *esw, int vport, 218 u32 max_rate, u32 min_rate); 219 int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw, 220 int vport, struct ifla_vf_info *ivi); 221 int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, 222 int vport, 223 struct ifla_vf_stats *vf_stats); 224 225 struct mlx5_flow_spec; 226 struct mlx5_esw_flow_attr; 227 228 struct mlx5_flow_handle * 229 mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw, 230 struct mlx5_flow_spec *spec, 231 struct mlx5_esw_flow_attr *attr); 232 void 233 mlx5_eswitch_del_offloaded_rule(struct mlx5_eswitch *esw, 234 struct mlx5_flow_handle *rule, 235 struct mlx5_esw_flow_attr *attr); 236 237 struct mlx5_flow_handle * 238 mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, int vport, u32 tirn); 239 240 enum { 241 SET_VLAN_STRIP = BIT(0), 242 SET_VLAN_INSERT = BIT(1) 243 }; 244 245 #define MLX5_FLOW_CONTEXT_ACTION_VLAN_POP 0x4000 246 #define MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH 0x8000 247 248 struct mlx5_esw_flow_attr { 249 struct mlx5_eswitch_rep *in_rep; 250 struct mlx5_eswitch_rep *out_rep; 251 252 int action; 253 u16 vlan; 254 bool vlan_handled; 255 u32 encap_id; 256 u32 mod_hdr_id; 257 struct mlx5e_tc_flow_parse_attr *parse_attr; 258 }; 259 260 int mlx5_eswitch_sqs2vport_start(struct mlx5_eswitch *esw, 261 struct mlx5_eswitch_rep *rep, 262 u16 *sqns_array, int sqns_num); 263 void mlx5_eswitch_sqs2vport_stop(struct mlx5_eswitch *esw, 264 struct mlx5_eswitch_rep *rep); 265 266 int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode); 267 int mlx5_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode); 268 int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode); 269 int mlx5_devlink_eswitch_inline_mode_get(struct devlink *devlink, u8 *mode); 270 int mlx5_eswitch_inline_mode_get(struct mlx5_eswitch *esw, int nvfs, u8 *mode); 271 int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, u8 encap); 272 int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap); 273 void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw, 274 int vport_index, 275 struct mlx5_eswitch_rep *rep); 276 void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw, 277 int vport_index); 278 struct net_device *mlx5_eswitch_get_uplink_netdev(struct mlx5_eswitch *esw); 279 280 int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw, 281 struct mlx5_esw_flow_attr *attr); 282 int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw, 283 struct mlx5_esw_flow_attr *attr); 284 int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw, 285 int vport, u16 vlan, u8 qos, u8 set_flags); 286 287 #define MLX5_DEBUG_ESWITCH_MASK BIT(3) 288 289 #define esw_info(dev, format, ...) \ 290 pr_info("(%s): E-Switch: " format, (dev)->priv.name, ##__VA_ARGS__) 291 292 #define esw_warn(dev, format, ...) \ 293 pr_warn("(%s): E-Switch: " format, (dev)->priv.name, ##__VA_ARGS__) 294 295 #define esw_debug(dev, format, ...) \ 296 mlx5_core_dbg_mask(dev, MLX5_DEBUG_ESWITCH_MASK, format, ##__VA_ARGS__) 297 #else /* CONFIG_MLX5_ESWITCH */ 298 /* eswitch API stubs */ 299 static inline int mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; } 300 static inline void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw) {} 301 static inline void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe) {} 302 static inline int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode) { return 0; } 303 static inline void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw) {} 304 #endif /* CONFIG_MLX5_ESWITCH */ 305 306 #endif /* __MLX5_ESWITCH_H__ */ 307