167ab160eSEdward Cree /* SPDX-License-Identifier: GPL-2.0-only */ 267ab160eSEdward Cree /**************************************************************************** 367ab160eSEdward Cree * Driver for Solarflare network controllers and boards 467ab160eSEdward Cree * Copyright 2019 Solarflare Communications Inc. 567ab160eSEdward Cree * Copyright 2020-2022 Xilinx Inc. 667ab160eSEdward Cree * 767ab160eSEdward Cree * This program is free software; you can redistribute it and/or modify it 867ab160eSEdward Cree * under the terms of the GNU General Public License version 2 as published 967ab160eSEdward Cree * by the Free Software Foundation, incorporated herein by reference. 1067ab160eSEdward Cree */ 1167ab160eSEdward Cree 1267ab160eSEdward Cree #ifndef EFX_TC_H 1367ab160eSEdward Cree #define EFX_TC_H 149dc0cad2SEdward Cree #include <net/flow_offload.h> 15f54a28a2SEdward Cree #include <linux/rhashtable.h> 1667ab160eSEdward Cree #include "net_driver.h" 1725730d8bSEdward Cree #include "tc_counters.h" 1867ab160eSEdward Cree 19c178dff3SEdward Cree #define IS_ALL_ONES(v) (!(typeof (v))~(v)) 20c178dff3SEdward Cree 21746224cdSEdward Cree #ifdef CONFIG_IPV6 22746224cdSEdward Cree static inline bool efx_ipv6_addr_all_ones(struct in6_addr *addr) 23746224cdSEdward Cree { 24746224cdSEdward Cree return !memchr_inv(addr, 0xff, sizeof(*addr)); 25746224cdSEdward Cree } 26746224cdSEdward Cree #endif 27746224cdSEdward Cree 28*b4da4235SEdward Cree struct efx_tc_encap_action; /* see tc_encap_actions.h */ 29*b4da4235SEdward Cree 3067ab160eSEdward Cree struct efx_tc_action_set { 3105ccd8d8SEdward Cree u16 vlan_push:2; 3205ccd8d8SEdward Cree u16 vlan_pop:2; 3317654d84SEdward Cree u16 decap:1; 3467ab160eSEdward Cree u16 deliver:1; 3505ccd8d8SEdward Cree __be16 vlan_tci[2]; /* TCIs for vlan_push */ 3605ccd8d8SEdward Cree __be16 vlan_proto[2]; /* Ethertypes for vlan_push */ 372e0f1eb0SEdward Cree struct efx_tc_counter_index *count; 38*b4da4235SEdward Cree struct efx_tc_encap_action *encap_md; /* entry in tc_encap_ht table */ 3967ab160eSEdward Cree u32 dest_mport; 4067ab160eSEdward Cree u32 fw_id; /* index of this entry in firmware actions table */ 4167ab160eSEdward Cree struct list_head list; 4267ab160eSEdward Cree }; 4367ab160eSEdward Cree 4467ab160eSEdward Cree struct efx_tc_match_fields { 4567ab160eSEdward Cree /* L1 */ 4667ab160eSEdward Cree u32 ingress_port; 47d902e1a7SEdward Cree u8 recirc_id; 486d1c604dSEdward Cree /* L2 (inner when encap) */ 496d1c604dSEdward Cree __be16 eth_proto; 506d1c604dSEdward Cree __be16 vlan_tci[2], vlan_proto[2]; 516d1c604dSEdward Cree u8 eth_saddr[ETH_ALEN], eth_daddr[ETH_ALEN]; 52c178dff3SEdward Cree /* L3 (when IP) */ 53c178dff3SEdward Cree u8 ip_proto, ip_tos, ip_ttl; 54c178dff3SEdward Cree __be32 src_ip, dst_ip; 55c178dff3SEdward Cree #ifdef CONFIG_IPV6 56c178dff3SEdward Cree struct in6_addr src_ip6, dst_ip6; 57c178dff3SEdward Cree #endif 585ca7ef29SEdward Cree bool ip_frag, ip_firstfrag; 595d1d24daSEdward Cree /* L4 */ 605d1d24daSEdward Cree __be16 l4_sport, l4_dport; /* Ports (UDP, TCP) */ 615d1d24daSEdward Cree __be16 tcp_flags; 62b9d5c9b7SEdward Cree /* Encap. The following are *outer* fields. Note that there are no 63b9d5c9b7SEdward Cree * outer eth (L2) fields; this is because TC doesn't have them. 64b9d5c9b7SEdward Cree */ 65b9d5c9b7SEdward Cree __be32 enc_src_ip, enc_dst_ip; 66b9d5c9b7SEdward Cree struct in6_addr enc_src_ip6, enc_dst_ip6; 67b9d5c9b7SEdward Cree u8 enc_ip_tos, enc_ip_ttl; 68b9d5c9b7SEdward Cree __be16 enc_sport, enc_dport; 69b9d5c9b7SEdward Cree __be32 enc_keyid; /* e.g. VNI, VSID */ 70b9d5c9b7SEdward Cree }; 71b9d5c9b7SEdward Cree 72b9d5c9b7SEdward Cree static inline bool efx_tc_match_is_encap(const struct efx_tc_match_fields *mask) 73b9d5c9b7SEdward Cree { 74b9d5c9b7SEdward Cree return mask->enc_src_ip || mask->enc_dst_ip || 75b9d5c9b7SEdward Cree !ipv6_addr_any(&mask->enc_src_ip6) || 76b9d5c9b7SEdward Cree !ipv6_addr_any(&mask->enc_dst_ip6) || mask->enc_ip_tos || 77b9d5c9b7SEdward Cree mask->enc_ip_ttl || mask->enc_sport || mask->enc_dport; 78b9d5c9b7SEdward Cree } 79b9d5c9b7SEdward Cree 803c9561c0SEdward Cree /** 813c9561c0SEdward Cree * enum efx_tc_em_pseudo_type - &struct efx_tc_encap_match pseudo type 823c9561c0SEdward Cree * 833c9561c0SEdward Cree * These are used to classify "pseudo" encap matches, which don't refer 843c9561c0SEdward Cree * to an entry in hardware but rather indicate that a section of the 853c9561c0SEdward Cree * match space is in use by another Outer Rule. 863c9561c0SEdward Cree * 873c9561c0SEdward Cree * @EFX_TC_EM_DIRECT: real HW entry in Outer Rule table; not a pseudo. 883c9561c0SEdward Cree * Hardware index in &struct efx_tc_encap_match.fw_id is valid. 893c9561c0SEdward Cree * @EFX_TC_EM_PSEUDO_MASK: registered by an encap match which includes a 90b6583d5eSEdward Cree * match on an optional field (currently ip_tos and/or udp_sport), 91b6583d5eSEdward Cree * to prevent an overlapping encap match _without_ optional fields. 923c9561c0SEdward Cree * The pseudo encap match may be referenced again by an encap match 93b6583d5eSEdward Cree * with different values for these fields, but all masks must match the 94b6583d5eSEdward Cree * first (stored in our child_* fields). 953c9561c0SEdward Cree */ 963c9561c0SEdward Cree enum efx_tc_em_pseudo_type { 973c9561c0SEdward Cree EFX_TC_EM_DIRECT, 983c9561c0SEdward Cree EFX_TC_EM_PSEUDO_MASK, 993c9561c0SEdward Cree }; 1003c9561c0SEdward Cree 101b9d5c9b7SEdward Cree struct efx_tc_encap_match { 102b9d5c9b7SEdward Cree __be32 src_ip, dst_ip; 103b9d5c9b7SEdward Cree struct in6_addr src_ip6, dst_ip6; 104b9d5c9b7SEdward Cree __be16 udp_dport; 105b6583d5eSEdward Cree __be16 udp_sport, udp_sport_mask; 10656beb35dSEdward Cree u8 ip_tos, ip_tos_mask; 107746224cdSEdward Cree struct rhash_head linkage; 1082245eb00SEdward Cree enum efx_encap_type tun_type; 1093c9561c0SEdward Cree u8 child_ip_tos_mask; 110b6583d5eSEdward Cree __be16 child_udp_sport_mask; 111746224cdSEdward Cree refcount_t ref; 1123c9561c0SEdward Cree enum efx_tc_em_pseudo_type type; 113b9d5c9b7SEdward Cree u32 fw_id; /* index of this entry in firmware encap match table */ 1143c9561c0SEdward Cree struct efx_tc_encap_match *pseudo; /* Referenced pseudo EM if needed */ 11567ab160eSEdward Cree }; 11667ab160eSEdward Cree 11767ab160eSEdward Cree struct efx_tc_match { 11867ab160eSEdward Cree struct efx_tc_match_fields value; 11967ab160eSEdward Cree struct efx_tc_match_fields mask; 120b9d5c9b7SEdward Cree struct efx_tc_encap_match *encap; 12167ab160eSEdward Cree }; 12267ab160eSEdward Cree 12367ab160eSEdward Cree struct efx_tc_action_set_list { 12467ab160eSEdward Cree struct list_head list; 12567ab160eSEdward Cree u32 fw_id; 12667ab160eSEdward Cree }; 12767ab160eSEdward Cree 12867ab160eSEdward Cree struct efx_tc_flow_rule { 129f54a28a2SEdward Cree unsigned long cookie; 130f54a28a2SEdward Cree struct rhash_head linkage; 13167ab160eSEdward Cree struct efx_tc_match match; 13267ab160eSEdward Cree struct efx_tc_action_set_list acts; 133*b4da4235SEdward Cree struct efx_tc_action_set_list *fallback; /* what to use when unready? */ 13467ab160eSEdward Cree u32 fw_id; 13567ab160eSEdward Cree }; 13667ab160eSEdward Cree 13767ab160eSEdward Cree enum efx_tc_rule_prios { 138d902e1a7SEdward Cree EFX_TC_PRIO_TC, /* Rule inserted by TC */ 13967ab160eSEdward Cree EFX_TC_PRIO_DFLT, /* Default switch rule; one of efx_tc_default_rules */ 14067ab160eSEdward Cree EFX_TC_PRIO__NUM 14167ab160eSEdward Cree }; 14267ab160eSEdward Cree 14367ab160eSEdward Cree /** 14467ab160eSEdward Cree * struct efx_tc_state - control plane data for TC offload 14567ab160eSEdward Cree * 1467ce3e235SEdward Cree * @caps: MAE capabilities reported by MCDI 1479dc0cad2SEdward Cree * @block_list: List of &struct efx_tc_block_binding 148f54a28a2SEdward Cree * @mutex: Used to serialise operations on TC hashtables 14919a0c989SEdward Cree * @counter_ht: Hashtable of TC counters (FW IDs and counter values) 15019a0c989SEdward Cree * @counter_id_ht: Hashtable mapping TC counter cookies to counters 151*b4da4235SEdward Cree * @encap_ht: Hashtable of TC encap actions 152746224cdSEdward Cree * @encap_match_ht: Hashtable of TC encap matches 153f54a28a2SEdward Cree * @match_action_ht: Hashtable of TC match-action rules 154e37f3b15SEdward Cree * @reps_mport_id: MAE port allocated for representor RX 155e37f3b15SEdward Cree * @reps_filter_uc: VNIC filter for representor unicast RX (promisc) 156e37f3b15SEdward Cree * @reps_filter_mc: VNIC filter for representor multicast RX (allmulti) 157e37f3b15SEdward Cree * @reps_mport_vport_id: vport_id for representor RX filters 158e5731274SEdward Cree * @flush_counters: counters have been stopped, waiting for drain 159e5731274SEdward Cree * @flush_gen: final generation count per type array as reported by 160e5731274SEdward Cree * MC_CMD_MAE_COUNTERS_STREAM_STOP 161e5731274SEdward Cree * @seen_gen: most recent generation count per type as seen by efx_tc_rx() 162e5731274SEdward Cree * @flush_wq: wait queue used by efx_mae_stop_counters() to wait for 163e5731274SEdward Cree * MAE counters RXQ to finish draining 16467ab160eSEdward Cree * @dflt: Match-action rules for default switching; at priority 16567ab160eSEdward Cree * %EFX_TC_PRIO_DFLT. Named by *ingress* port 16667ab160eSEdward Cree * @dflt.pf: rule for traffic ingressing from PF (egresses to wire) 16767ab160eSEdward Cree * @dflt.wire: rule for traffic ingressing from wire (egresses to PF) 168e16ca7fbSEdward Cree * @facts: Fallback action-set-lists for unready rules. Named by *egress* port 169e16ca7fbSEdward Cree * @facts.pf: action-set-list for unready rules on PF netdev, hence applying to 170e16ca7fbSEdward Cree * traffic from wire, and egressing to PF 171e16ca7fbSEdward Cree * @facts.reps: action-set-list for unready rules on representors, hence 172e16ca7fbSEdward Cree * applying to traffic from representees, and egressing to the reps mport 1739dc0cad2SEdward Cree * @up: have TC datastructures been set up? 17467ab160eSEdward Cree */ 17567ab160eSEdward Cree struct efx_tc_state { 1767ce3e235SEdward Cree struct mae_caps *caps; 1779dc0cad2SEdward Cree struct list_head block_list; 178f54a28a2SEdward Cree struct mutex mutex; 17919a0c989SEdward Cree struct rhashtable counter_ht; 18019a0c989SEdward Cree struct rhashtable counter_id_ht; 181*b4da4235SEdward Cree struct rhashtable encap_ht; 182746224cdSEdward Cree struct rhashtable encap_match_ht; 183f54a28a2SEdward Cree struct rhashtable match_action_ht; 184e37f3b15SEdward Cree u32 reps_mport_id, reps_mport_vport_id; 185e37f3b15SEdward Cree s32 reps_filter_uc, reps_filter_mc; 186e5731274SEdward Cree bool flush_counters; 187e5731274SEdward Cree u32 flush_gen[EFX_TC_COUNTER_TYPE_MAX]; 188e5731274SEdward Cree u32 seen_gen[EFX_TC_COUNTER_TYPE_MAX]; 189e5731274SEdward Cree wait_queue_head_t flush_wq; 19067ab160eSEdward Cree struct { 19167ab160eSEdward Cree struct efx_tc_flow_rule pf; 19267ab160eSEdward Cree struct efx_tc_flow_rule wire; 19367ab160eSEdward Cree } dflt; 194e16ca7fbSEdward Cree struct { 195e16ca7fbSEdward Cree struct efx_tc_action_set_list pf; 196e16ca7fbSEdward Cree struct efx_tc_action_set_list reps; 197e16ca7fbSEdward Cree } facts; 1989dc0cad2SEdward Cree bool up; 19967ab160eSEdward Cree }; 20067ab160eSEdward Cree 20167ab160eSEdward Cree struct efx_rep; 20267ab160eSEdward Cree 203*b4da4235SEdward Cree enum efx_encap_type efx_tc_indr_netdev_type(struct net_device *net_dev); 20467ab160eSEdward Cree int efx_tc_configure_default_rule_rep(struct efx_rep *efv); 20567ab160eSEdward Cree void efx_tc_deconfigure_default_rule(struct efx_nic *efx, 20667ab160eSEdward Cree struct efx_tc_flow_rule *rule); 2079dc0cad2SEdward Cree int efx_tc_flower(struct efx_nic *efx, struct net_device *net_dev, 2089dc0cad2SEdward Cree struct flow_cls_offload *tc, struct efx_rep *efv); 20967ab160eSEdward Cree 210e37f3b15SEdward Cree int efx_tc_insert_rep_filters(struct efx_nic *efx); 211e37f3b15SEdward Cree void efx_tc_remove_rep_filters(struct efx_nic *efx); 212e37f3b15SEdward Cree 21367ab160eSEdward Cree int efx_init_tc(struct efx_nic *efx); 21467ab160eSEdward Cree void efx_fini_tc(struct efx_nic *efx); 21567ab160eSEdward Cree 21667ab160eSEdward Cree int efx_init_struct_tc(struct efx_nic *efx); 21767ab160eSEdward Cree void efx_fini_struct_tc(struct efx_nic *efx); 21867ab160eSEdward Cree 21967ab160eSEdward Cree #endif /* EFX_TC_H */ 220