1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2019-2021 Xilinx, Inc. 4 * Copyright(c) 2019 Solarflare Communications Inc. 5 * 6 * This software was jointly developed between OKTET Labs (under contract 7 * for Solarflare) and Solarflare Communications, Inc. 8 */ 9 10 #ifndef _SFC_MAE_H 11 #define _SFC_MAE_H 12 13 #include <stdbool.h> 14 15 #include <rte_spinlock.h> 16 17 #include "efx.h" 18 19 #include "sfc_stats.h" 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 /** FW-allocatable resource context */ 26 struct sfc_mae_fw_rsrc { 27 unsigned int refcnt; 28 RTE_STD_C11 29 union { 30 efx_mae_aset_id_t aset_id; 31 efx_mae_rule_id_t rule_id; 32 efx_mae_eh_id_t eh_id; 33 }; 34 }; 35 36 /** Outer rule registry entry */ 37 struct sfc_mae_outer_rule { 38 TAILQ_ENTRY(sfc_mae_outer_rule) entries; 39 unsigned int refcnt; 40 efx_mae_match_spec_t *match_spec; 41 efx_tunnel_protocol_t encap_type; 42 struct sfc_mae_fw_rsrc fw_rsrc; 43 }; 44 45 TAILQ_HEAD(sfc_mae_outer_rules, sfc_mae_outer_rule); 46 47 /** Encap. header registry entry */ 48 struct sfc_mae_encap_header { 49 TAILQ_ENTRY(sfc_mae_encap_header) entries; 50 unsigned int refcnt; 51 uint8_t *buf; 52 size_t size; 53 efx_tunnel_protocol_t type; 54 struct sfc_mae_fw_rsrc fw_rsrc; 55 }; 56 57 TAILQ_HEAD(sfc_mae_encap_headers, sfc_mae_encap_header); 58 59 /* Counter ID */ 60 struct sfc_mae_counter_id { 61 /* ID of a counter in MAE */ 62 efx_counter_t mae_id; 63 /* ID of a counter in RTE */ 64 uint32_t rte_id; 65 /* RTE counter ID validity status */ 66 bool rte_id_valid; 67 68 /* Flow Tunnel (FT) GROUP hit counter (or NULL) */ 69 uint64_t *ft_group_hit_counter; 70 /* Flow Tunnel (FT) context (for JUMP rules; otherwise, NULL) */ 71 struct sfc_flow_tunnel *ft; 72 }; 73 74 /** Action set registry entry */ 75 struct sfc_mae_action_set { 76 TAILQ_ENTRY(sfc_mae_action_set) entries; 77 unsigned int refcnt; 78 struct sfc_mae_counter_id *counters; 79 uint32_t n_counters; 80 efx_mae_actions_t *spec; 81 struct sfc_mae_encap_header *encap_header; 82 struct sfc_mae_fw_rsrc fw_rsrc; 83 }; 84 85 TAILQ_HEAD(sfc_mae_action_sets, sfc_mae_action_set); 86 87 /** Options for MAE support status */ 88 enum sfc_mae_status { 89 SFC_MAE_STATUS_UNKNOWN = 0, 90 SFC_MAE_STATUS_UNSUPPORTED, 91 SFC_MAE_STATUS_SUPPORTED, 92 SFC_MAE_STATUS_ADMIN, 93 }; 94 95 /* 96 * Encap. header bounce buffer. It is used to store header data 97 * when parsing the header definition in the action VXLAN_ENCAP. 98 */ 99 struct sfc_mae_bounce_eh { 100 uint8_t *buf; 101 size_t buf_size; 102 size_t size; 103 efx_tunnel_protocol_t type; 104 }; 105 106 /** Counter collection entry */ 107 struct sfc_mae_counter { 108 bool inuse; 109 uint32_t generation_count; 110 union sfc_pkts_bytes value; 111 union sfc_pkts_bytes reset; 112 113 uint64_t *ft_group_hit_counter; 114 }; 115 116 struct sfc_mae_counters_xstats { 117 uint64_t not_inuse_update; 118 uint64_t realloc_update; 119 }; 120 121 struct sfc_mae_counters { 122 /** An array of all MAE counters */ 123 struct sfc_mae_counter *mae_counters; 124 /** Extra statistics for counters */ 125 struct sfc_mae_counters_xstats xstats; 126 /** Count of all MAE counters */ 127 unsigned int n_mae_counters; 128 }; 129 130 /** Options for MAE counter polling mode */ 131 enum sfc_mae_counter_polling_mode { 132 SFC_MAE_COUNTER_POLLING_OFF = 0, 133 SFC_MAE_COUNTER_POLLING_SERVICE, 134 SFC_MAE_COUNTER_POLLING_THREAD, 135 }; 136 137 struct sfc_mae_counter_registry { 138 /* Common counter information */ 139 /** Counters collection */ 140 struct sfc_mae_counters counters; 141 142 /* Information used by counter update service */ 143 /** Callback to get packets from RxQ */ 144 eth_rx_burst_t rx_pkt_burst; 145 /** Data for the callback to get packets */ 146 struct sfc_dp_rxq *rx_dp; 147 /** Number of buffers pushed to the RxQ */ 148 unsigned int pushed_n_buffers; 149 /** Are credits used by counter stream */ 150 bool use_credits; 151 152 /* Information used by configuration routines */ 153 enum sfc_mae_counter_polling_mode polling_mode; 154 union { 155 struct { 156 /** Counter service core ID */ 157 uint32_t core_id; 158 /** Counter service ID */ 159 uint32_t id; 160 } service; 161 struct { 162 /** Counter thread ID */ 163 pthread_t id; 164 /** The thread should keep running */ 165 bool run; 166 } thread; 167 } polling; 168 }; 169 170 /** 171 * MAE rules used to capture traffic generated by VFs and direct it to 172 * representors (one for each VF). 173 */ 174 #define SFC_MAE_NB_REPR_RULES_MAX (64) 175 176 /** Rules to forward traffic from PHY port to PF and from PF to PHY port */ 177 #define SFC_MAE_NB_SWITCHDEV_RULES (2) 178 /** Maximum required internal MAE rules */ 179 #define SFC_MAE_NB_RULES_MAX (SFC_MAE_NB_SWITCHDEV_RULES + \ 180 SFC_MAE_NB_REPR_RULES_MAX) 181 182 struct sfc_mae_rule { 183 efx_mae_match_spec_t *spec; 184 efx_mae_actions_t *actions; 185 efx_mae_aset_id_t action_set; 186 efx_mae_rule_id_t rule_id; 187 }; 188 189 struct sfc_mae_internal_rules { 190 /* 191 * Rules required to sustain switchdev mode or to provide 192 * port representor functionality. 193 */ 194 struct sfc_mae_rule rules[SFC_MAE_NB_RULES_MAX]; 195 }; 196 197 struct sfc_mae { 198 /** Assigned switch domain identifier */ 199 uint16_t switch_domain_id; 200 /** Assigned switch port identifier */ 201 uint16_t switch_port_id; 202 /** NIC support for MAE status */ 203 enum sfc_mae_status status; 204 /** Priority level limit for MAE outer rules */ 205 unsigned int nb_outer_rule_prios_max; 206 /** Priority level limit for MAE action rules */ 207 unsigned int nb_action_rule_prios_max; 208 /** Encapsulation support status */ 209 uint32_t encap_types_supported; 210 /** Outer rule registry */ 211 struct sfc_mae_outer_rules outer_rules; 212 /** Encap. header registry */ 213 struct sfc_mae_encap_headers encap_headers; 214 /** Action set registry */ 215 struct sfc_mae_action_sets action_sets; 216 /** Encap. header bounce buffer */ 217 struct sfc_mae_bounce_eh bounce_eh; 218 /** Flag indicating whether counter-only RxQ is running */ 219 bool counter_rxq_running; 220 /** Counter registry */ 221 struct sfc_mae_counter_registry counter_registry; 222 /** Driver-internal flow rules */ 223 struct sfc_mae_internal_rules internal_rules; 224 /** 225 * Switchdev default rules. They forward traffic from PHY port 226 * to PF and vice versa. 227 */ 228 struct sfc_mae_rule *switchdev_rule_pf_to_ext; 229 struct sfc_mae_rule *switchdev_rule_ext_to_pf; 230 }; 231 232 struct sfc_adapter; 233 struct sfc_flow_spec; 234 235 /** This implementation supports double-tagging */ 236 #define SFC_MAE_MATCH_VLAN_MAX_NTAGS (2) 237 238 /** It is possible to keep track of one item ETH and two items VLAN */ 239 #define SFC_MAE_L2_MAX_NITEMS (SFC_MAE_MATCH_VLAN_MAX_NTAGS + 1) 240 241 /** Auxiliary entry format to keep track of L2 "type" ("inner_type") */ 242 struct sfc_mae_ethertype { 243 rte_be16_t value; 244 rte_be16_t mask; 245 }; 246 247 struct sfc_mae_pattern_data { 248 /** 249 * Keeps track of "type" ("inner_type") mask and value for each 250 * parsed L2 item in a pattern. These values/masks get filled 251 * in MAE match specification at the end of parsing. Also, this 252 * information is used to conduct consistency checks: 253 * 254 * - If an item ETH is followed by a single item VLAN, 255 * the former must have "type" set to one of supported 256 * TPID values (0x8100, 0x88a8, 0x9100, 0x9200, 0x9300), 257 * or 0x0000/0x0000. 258 * 259 * - If an item ETH is followed by two items VLAN, the 260 * item ETH must have "type" set to one of supported TPID 261 * values (0x88a8, 0x9100, 0x9200, 0x9300), or 0x0000/0x0000, 262 * and the outermost VLAN item must have "inner_type" set 263 * to TPID value 0x8100, or 0x0000/0x0000 264 * 265 * - If a L2 item is followed by a L3 one, the former must 266 * indicate "type" ("inner_type") which corresponds to 267 * the protocol used in the L3 item, or 0x0000/0x0000. 268 * 269 * In turn, mapping between RTE convention (above requirements) and 270 * MAE fields is non-trivial. The following scheme indicates 271 * which item EtherTypes go to which MAE fields in the case 272 * of single tag: 273 * 274 * ETH (0x8100) --> VLAN0_PROTO_BE 275 * VLAN (L3 EtherType) --> ETHER_TYPE_BE 276 * 277 * Similarly, in the case of double tagging: 278 * 279 * ETH (0x88a8) --> VLAN0_PROTO_BE 280 * VLAN (0x8100) --> VLAN1_PROTO_BE 281 * VLAN (L3 EtherType) --> ETHER_TYPE_BE 282 */ 283 struct sfc_mae_ethertype ethertypes[SFC_MAE_L2_MAX_NITEMS]; 284 285 rte_be16_t tci_masks[SFC_MAE_MATCH_VLAN_MAX_NTAGS]; 286 287 unsigned int nb_vlan_tags; 288 289 /** 290 * L3 requirement for the innermost L2 item's "type" ("inner_type"). 291 * This contains one of: 292 * - 0x0800/0xffff: IPV4 293 * - 0x86dd/0xffff: IPV6 294 * - 0x0000/0x0000: no L3 item 295 */ 296 struct sfc_mae_ethertype innermost_ethertype_restriction; 297 298 /** 299 * The following two fields keep track of L3 "proto" mask and value. 300 * The corresponding fields get filled in MAE match specification 301 * at the end of parsing. Also, the information is used by a 302 * post-check to enforce consistency requirements: 303 * 304 * - If a L3 item is followed by an item TCP, the former has 305 * its "proto" set to either 0x06/0xff or 0x00/0x00. 306 * 307 * - If a L3 item is followed by an item UDP, the former has 308 * its "proto" set to either 0x11/0xff or 0x00/0x00. 309 */ 310 uint8_t l3_next_proto_value; 311 uint8_t l3_next_proto_mask; 312 313 /* 314 * L4 requirement for L3 item's "proto". 315 * This contains one of: 316 * - 0x06/0xff: TCP 317 * - 0x11/0xff: UDP 318 * - 0x00/0x00: no L4 item 319 */ 320 uint8_t l3_next_proto_restriction_value; 321 uint8_t l3_next_proto_restriction_mask; 322 323 /* Projected state of EFX_MAE_FIELD_HAS_OVLAN match bit */ 324 bool has_ovlan_value; 325 bool has_ovlan_mask; 326 327 /* Projected state of EFX_MAE_FIELD_HAS_IVLAN match bit */ 328 bool has_ivlan_value; 329 bool has_ivlan_mask; 330 }; 331 332 struct sfc_mae_parse_ctx { 333 struct sfc_adapter *sa; 334 efx_mae_match_spec_t *match_spec_action; 335 efx_mae_match_spec_t *match_spec_outer; 336 /* 337 * This points to either of the above two specifications depending 338 * on which part of the pattern is being parsed (outer / inner). 339 */ 340 efx_mae_match_spec_t *match_spec; 341 /* 342 * This points to either "field_ids_remap_to_encap" 343 * or "field_ids_no_remap" (see sfc_mae.c) depending on 344 * which part of the pattern is being parsed. 345 */ 346 const efx_mae_field_id_t *field_ids_remap; 347 /* These two fields correspond to the tunnel-specific default mask. */ 348 size_t tunnel_def_mask_size; 349 const void *tunnel_def_mask; 350 bool match_mport_set; 351 enum sfc_flow_tunnel_rule_type ft_rule_type; 352 struct sfc_mae_pattern_data pattern_data; 353 efx_tunnel_protocol_t encap_type; 354 const struct rte_flow_item *pattern; 355 unsigned int priority; 356 struct sfc_flow_tunnel *ft; 357 }; 358 359 int sfc_mae_attach(struct sfc_adapter *sa); 360 void sfc_mae_detach(struct sfc_adapter *sa); 361 sfc_flow_cleanup_cb_t sfc_mae_flow_cleanup; 362 int sfc_mae_rule_parse_pattern(struct sfc_adapter *sa, 363 const struct rte_flow_item pattern[], 364 struct sfc_flow_spec_mae *spec, 365 struct rte_flow_error *error); 366 int sfc_mae_rule_parse_actions(struct sfc_adapter *sa, 367 const struct rte_flow_action actions[], 368 struct sfc_flow_spec_mae *spec_mae, 369 struct rte_flow_error *error); 370 sfc_flow_verify_cb_t sfc_mae_flow_verify; 371 sfc_flow_insert_cb_t sfc_mae_flow_insert; 372 sfc_flow_remove_cb_t sfc_mae_flow_remove; 373 sfc_flow_query_cb_t sfc_mae_flow_query; 374 375 /** 376 * The value used to represent the lowest priority. 377 * Used in MAE rule API. 378 */ 379 #define SFC_MAE_RULE_PRIO_LOWEST (-1) 380 381 /** 382 * Insert a driver-internal flow rule that matches traffic originating from 383 * some m-port selector and redirects it to another one 384 * (eg. PF --> PHY, PHY --> PF). 385 * 386 * If requested priority is negative, use the lowest priority. 387 */ 388 int sfc_mae_rule_add_mport_match_deliver(struct sfc_adapter *sa, 389 const efx_mport_sel_t *mport_match, 390 const efx_mport_sel_t *mport_deliver, 391 int prio, struct sfc_mae_rule **rulep); 392 void sfc_mae_rule_del(struct sfc_adapter *sa, struct sfc_mae_rule *rule); 393 int sfc_mae_switchdev_init(struct sfc_adapter *sa); 394 void sfc_mae_switchdev_fini(struct sfc_adapter *sa); 395 396 #ifdef __cplusplus 397 } 398 #endif 399 #endif /* _SFC_MAE_H */ 400