1 /*- 2 * Copyright (c) 2013-2017, Mellanox Technologies, Ltd. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 #ifndef _MLX5_FS_ 27 #define _MLX5_FS_ 28 29 #include <linux/list.h> 30 #include <linux/bitops.h> 31 32 #include <dev/mlx5/mlx5_ifc.h> 33 #include <dev/mlx5/device.h> 34 #include <dev/mlx5/driver.h> 35 36 enum { 37 MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO = 1 << 16, 38 }; 39 40 /*Flow tag*/ 41 enum { 42 MLX5_FS_DEFAULT_FLOW_TAG = 0xFFFFFF, 43 MLX5_FS_ETH_FLOW_TAG = 0xFFFFFE, 44 MLX5_FS_SNIFFER_FLOW_TAG = 0xFFFFFD, 45 }; 46 47 enum mlx5_rule_fwd_action { 48 MLX5_FLOW_RULE_FWD_ACTION_ALLOW = 0x1, 49 MLX5_FLOW_RULE_FWD_ACTION_DROP = 0x2, 50 MLX5_FLOW_RULE_FWD_ACTION_DEST = 0x4, 51 }; 52 53 enum { 54 MLX5_FS_FLOW_TAG_MASK = 0xFFFFFF, 55 }; 56 57 #define FS_MAX_TYPES 10 58 #define FS_MAX_ENTRIES 32000U 59 60 #define FS_REFORMAT_KEYWORD "_reformat" 61 62 enum mlx5_flow_namespace_type { 63 MLX5_FLOW_NAMESPACE_BYPASS, 64 MLX5_FLOW_NAMESPACE_OFFLOADS, 65 MLX5_FLOW_NAMESPACE_KERNEL, 66 MLX5_FLOW_NAMESPACE_LEFTOVERS, 67 MLX5_FLOW_NAMESPACE_SNIFFER_RX, 68 MLX5_FLOW_NAMESPACE_SNIFFER_TX, 69 MLX5_FLOW_NAMESPACE_FDB, 70 MLX5_FLOW_NAMESPACE_ESW_EGRESS, 71 MLX5_FLOW_NAMESPACE_ESW_INGRESS, 72 }; 73 74 struct mlx5_flow_table; 75 struct mlx5_flow_group; 76 struct mlx5_flow_rule; 77 struct mlx5_flow_namespace; 78 79 struct mlx5_flow_spec { 80 u8 match_criteria_enable; 81 u32 match_criteria[MLX5_ST_SZ_DW(fte_match_param)]; 82 u32 match_value[MLX5_ST_SZ_DW(fte_match_param)]; 83 }; 84 85 struct mlx5_flow_destination { 86 u32 type; 87 union { 88 u32 tir_num; 89 struct mlx5_flow_table *ft; 90 u32 vport_num; 91 }; 92 }; 93 94 enum mlx5_flow_act_actions { 95 MLX5_FLOW_ACT_ACTIONS_FLOW_TAG = 1 << 0, 96 MLX5_FLOW_ACT_ACTIONS_MODIFY_HDR = 1 << 1, 97 MLX5_FLOW_ACT_ACTIONS_PACKET_REFORMAT = 1 << 2, 98 MLX5_FLOW_ACT_ACTIONS_COUNT = 1 << 3, 99 }; 100 101 enum MLX5_FLOW_ACT_FLAGS { 102 MLX5_FLOW_ACT_NO_APPEND = 1 << 0, 103 }; 104 105 struct mlx5_flow_act { 106 u32 actions; /* See enum mlx5_flow_act_actions */ 107 u32 flags; 108 u32 flow_tag; 109 struct mlx5_modify_hdr *modify_hdr; 110 struct mlx5_pkt_reformat *pkt_reformat; 111 struct mlx5_fc *counter; 112 }; 113 114 #define FT_NAME_STR_SZ 20 115 #define LEFTOVERS_RULE_NUM 2 116 static inline void build_leftovers_ft_param(char *name, 117 unsigned int *priority, 118 int *n_ent, 119 int *n_grp) 120 { 121 snprintf(name, FT_NAME_STR_SZ, "leftovers"); 122 *priority = 0; /*Priority of leftovers_prio-0*/ 123 *n_ent = LEFTOVERS_RULE_NUM + 1; /*1: star rules*/ 124 *n_grp = LEFTOVERS_RULE_NUM; 125 } 126 127 static inline bool outer_header_zero(u32 *match_criteria) 128 { 129 int size = MLX5_ST_SZ_BYTES(fte_match_param); 130 char *outer_headers_c = MLX5_ADDR_OF(fte_match_param, match_criteria, 131 outer_headers); 132 133 return outer_headers_c[0] == 0 && !memcmp(outer_headers_c, 134 outer_headers_c + 1, 135 size - 1); 136 } 137 138 struct mlx5_flow_namespace * 139 mlx5_get_flow_namespace(struct mlx5_core_dev *dev, 140 enum mlx5_flow_namespace_type type); 141 142 /* The underlying implementation create two more entries for 143 * chaining flow tables. the user should be aware that if he pass 144 * max_num_ftes as 2^N it will result in doubled size flow table 145 */ 146 struct mlx5_flow_table * 147 mlx5_create_auto_grouped_flow_table(struct mlx5_flow_namespace *ns, 148 int prio, 149 const char *name, 150 int num_flow_table_entries, 151 int max_num_groups, 152 int num_reserved_entries); 153 154 struct mlx5_flow_table * 155 mlx5_create_vport_flow_table(struct mlx5_flow_namespace *ns, 156 u16 vport, 157 int prio, 158 const char *name, 159 int num_flow_table_entries); 160 161 struct mlx5_flow_table * 162 mlx5_create_flow_table(struct mlx5_flow_namespace *ns, 163 int prio, 164 const char *name, 165 int num_flow_table_entries); 166 int mlx5_destroy_flow_table(struct mlx5_flow_table *ft); 167 168 /* inbox should be set with the following values: 169 * start_flow_index 170 * end_flow_index 171 * match_criteria_enable 172 * match_criteria 173 */ 174 struct mlx5_flow_group * 175 mlx5_create_flow_group(struct mlx5_flow_table *ft, u32 *in); 176 void mlx5_destroy_flow_group(struct mlx5_flow_group *fg); 177 178 /* Single destination per rule. 179 * Group ID is implied by the match criteria. 180 */ 181 struct mlx5_flow_rule * 182 mlx5_add_flow_rule(struct mlx5_flow_table *ft, 183 u8 match_criteria_enable, 184 u32 *match_criteria, 185 u32 *match_value, 186 u32 sw_action, 187 struct mlx5_flow_act *flow_act, 188 struct mlx5_flow_destination *dest); 189 void mlx5_del_flow_rule(struct mlx5_flow_rule **); 190 191 /*The following API is for sniffer*/ 192 typedef int (*rule_event_fn)(struct mlx5_flow_rule *rule, 193 bool ctx_changed, 194 void *client_data, 195 void *context); 196 197 struct mlx5_flow_handler; 198 199 struct flow_client_priv_data; 200 201 void mlx5e_sniffer_roce_mode_notify( 202 struct mlx5_core_dev *mdev, 203 int action); 204 205 int mlx5_set_rule_private_data(struct mlx5_flow_rule *rule, struct 206 mlx5_flow_handler *handler, void 207 *client_data); 208 209 struct mlx5_flow_handler *mlx5_register_rule_notifier(struct mlx5_core_dev *dev, 210 enum mlx5_flow_namespace_type ns_type, 211 rule_event_fn add_cb, 212 rule_event_fn del_cb, 213 void *context); 214 215 void mlx5_unregister_rule_notifier(struct mlx5_flow_handler *handler); 216 217 void mlx5_flow_iterate_existing_rules(struct mlx5_flow_namespace *ns, 218 rule_event_fn cb, 219 void *context); 220 221 void mlx5_get_match_criteria(u32 *match_criteria, 222 struct mlx5_flow_rule *rule); 223 224 void mlx5_get_match_value(u32 *match_value, 225 struct mlx5_flow_rule *rule); 226 227 u8 mlx5_get_match_criteria_enable(struct mlx5_flow_rule *rule); 228 229 struct mlx5_flow_rules_list *get_roce_flow_rules(u8 roce_mode); 230 231 void mlx5_del_flow_rules_list(struct mlx5_flow_rules_list *rules_list); 232 233 struct mlx5_flow_rules_list { 234 struct list_head head; 235 }; 236 237 struct mlx5_flow_rule_node { 238 struct list_head list; 239 u32 match_criteria[MLX5_ST_SZ_DW(fte_match_param)]; 240 u32 match_value[MLX5_ST_SZ_DW(fte_match_param)]; 241 u8 match_criteria_enable; 242 }; 243 244 struct mlx5_core_fs_mask { 245 u8 match_criteria_enable; 246 u32 match_criteria[MLX5_ST_SZ_DW(fte_match_param)]; 247 }; 248 249 bool fs_match_exact_val( 250 struct mlx5_core_fs_mask *mask, 251 void *val1, 252 void *val2); 253 254 bool fs_match_exact_mask( 255 u8 match_criteria_enable1, 256 u8 match_criteria_enable2, 257 void *mask1, 258 void *mask2); 259 /**********end API for sniffer**********/ 260 struct mlx5_modify_hdr *mlx5_modify_header_alloc(struct mlx5_core_dev *dev, 261 enum mlx5_flow_namespace_type ns_type, 262 u8 num_actions, 263 void *modify_actions); 264 void mlx5_modify_header_dealloc(struct mlx5_core_dev *dev, 265 struct mlx5_modify_hdr *modify_hdr); 266 267 struct mlx5_pkt_reformat_params { 268 int type; 269 u8 param_0; 270 u8 param_1; 271 size_t size; 272 void *data; 273 }; 274 275 struct mlx5_pkt_reformat *mlx5_packet_reformat_alloc(struct mlx5_core_dev *dev, 276 struct mlx5_pkt_reformat_params *params, 277 enum mlx5_flow_namespace_type ns_type); 278 void mlx5_packet_reformat_dealloc(struct mlx5_core_dev *dev, 279 struct mlx5_pkt_reformat *pkt_reformat); 280 /********** Flow counters API **********/ 281 struct mlx5_fc; 282 struct mlx5_fc *mlx5_fc_create(struct mlx5_core_dev *dev, bool aging); 283 284 /* As mlx5_fc_create() but doesn't queue stats refresh thread. */ 285 struct mlx5_fc *mlx5_fc_create_ex(struct mlx5_core_dev *dev, bool aging); 286 287 void mlx5_fc_destroy(struct mlx5_core_dev *dev, struct mlx5_fc *counter); 288 u64 mlx5_fc_query_lastuse(struct mlx5_fc *counter); 289 void mlx5_fc_query_cached(struct mlx5_fc *counter, 290 u64 *bytes, u64 *packets, u64 *lastuse); 291 int mlx5_fc_query(struct mlx5_core_dev *dev, struct mlx5_fc *counter, 292 u64 *packets, u64 *bytes); 293 u32 mlx5_fc_id(struct mlx5_fc *counter); 294 /******* End of Flow counters API ******/ 295 #endif 296