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 2167ab160eSEdward Cree struct efx_tc_action_set { 2205ccd8d8SEdward Cree u16 vlan_push:2; 2305ccd8d8SEdward Cree u16 vlan_pop:2; 2467ab160eSEdward Cree u16 deliver:1; 2505ccd8d8SEdward Cree __be16 vlan_tci[2]; /* TCIs for vlan_push */ 2605ccd8d8SEdward Cree __be16 vlan_proto[2]; /* Ethertypes for vlan_push */ 272e0f1eb0SEdward Cree struct efx_tc_counter_index *count; 2867ab160eSEdward Cree u32 dest_mport; 2967ab160eSEdward Cree u32 fw_id; /* index of this entry in firmware actions table */ 3067ab160eSEdward Cree struct list_head list; 3167ab160eSEdward Cree }; 3267ab160eSEdward Cree 3367ab160eSEdward Cree struct efx_tc_match_fields { 3467ab160eSEdward Cree /* L1 */ 3567ab160eSEdward Cree u32 ingress_port; 36d902e1a7SEdward Cree u8 recirc_id; 376d1c604dSEdward Cree /* L2 (inner when encap) */ 386d1c604dSEdward Cree __be16 eth_proto; 396d1c604dSEdward Cree __be16 vlan_tci[2], vlan_proto[2]; 406d1c604dSEdward Cree u8 eth_saddr[ETH_ALEN], eth_daddr[ETH_ALEN]; 41c178dff3SEdward Cree /* L3 (when IP) */ 42c178dff3SEdward Cree u8 ip_proto, ip_tos, ip_ttl; 43c178dff3SEdward Cree __be32 src_ip, dst_ip; 44c178dff3SEdward Cree #ifdef CONFIG_IPV6 45c178dff3SEdward Cree struct in6_addr src_ip6, dst_ip6; 46c178dff3SEdward Cree #endif 475ca7ef29SEdward Cree bool ip_frag, ip_firstfrag; 485d1d24daSEdward Cree /* L4 */ 495d1d24daSEdward Cree __be16 l4_sport, l4_dport; /* Ports (UDP, TCP) */ 505d1d24daSEdward Cree __be16 tcp_flags; 51*b9d5c9b7SEdward Cree /* Encap. The following are *outer* fields. Note that there are no 52*b9d5c9b7SEdward Cree * outer eth (L2) fields; this is because TC doesn't have them. 53*b9d5c9b7SEdward Cree */ 54*b9d5c9b7SEdward Cree __be32 enc_src_ip, enc_dst_ip; 55*b9d5c9b7SEdward Cree struct in6_addr enc_src_ip6, enc_dst_ip6; 56*b9d5c9b7SEdward Cree u8 enc_ip_tos, enc_ip_ttl; 57*b9d5c9b7SEdward Cree __be16 enc_sport, enc_dport; 58*b9d5c9b7SEdward Cree __be32 enc_keyid; /* e.g. VNI, VSID */ 59*b9d5c9b7SEdward Cree }; 60*b9d5c9b7SEdward Cree 61*b9d5c9b7SEdward Cree static inline bool efx_tc_match_is_encap(const struct efx_tc_match_fields *mask) 62*b9d5c9b7SEdward Cree { 63*b9d5c9b7SEdward Cree return mask->enc_src_ip || mask->enc_dst_ip || 64*b9d5c9b7SEdward Cree !ipv6_addr_any(&mask->enc_src_ip6) || 65*b9d5c9b7SEdward Cree !ipv6_addr_any(&mask->enc_dst_ip6) || mask->enc_ip_tos || 66*b9d5c9b7SEdward Cree mask->enc_ip_ttl || mask->enc_sport || mask->enc_dport; 67*b9d5c9b7SEdward Cree } 68*b9d5c9b7SEdward Cree 69*b9d5c9b7SEdward Cree struct efx_tc_encap_match { 70*b9d5c9b7SEdward Cree __be32 src_ip, dst_ip; 71*b9d5c9b7SEdward Cree struct in6_addr src_ip6, dst_ip6; 72*b9d5c9b7SEdward Cree __be16 udp_dport; 73*b9d5c9b7SEdward Cree u32 fw_id; /* index of this entry in firmware encap match table */ 7467ab160eSEdward Cree }; 7567ab160eSEdward Cree 7667ab160eSEdward Cree struct efx_tc_match { 7767ab160eSEdward Cree struct efx_tc_match_fields value; 7867ab160eSEdward Cree struct efx_tc_match_fields mask; 79*b9d5c9b7SEdward Cree struct efx_tc_encap_match *encap; 8067ab160eSEdward Cree }; 8167ab160eSEdward Cree 8267ab160eSEdward Cree struct efx_tc_action_set_list { 8367ab160eSEdward Cree struct list_head list; 8467ab160eSEdward Cree u32 fw_id; 8567ab160eSEdward Cree }; 8667ab160eSEdward Cree 8767ab160eSEdward Cree struct efx_tc_flow_rule { 88f54a28a2SEdward Cree unsigned long cookie; 89f54a28a2SEdward Cree struct rhash_head linkage; 9067ab160eSEdward Cree struct efx_tc_match match; 9167ab160eSEdward Cree struct efx_tc_action_set_list acts; 9267ab160eSEdward Cree u32 fw_id; 9367ab160eSEdward Cree }; 9467ab160eSEdward Cree 9567ab160eSEdward Cree enum efx_tc_rule_prios { 96d902e1a7SEdward Cree EFX_TC_PRIO_TC, /* Rule inserted by TC */ 9767ab160eSEdward Cree EFX_TC_PRIO_DFLT, /* Default switch rule; one of efx_tc_default_rules */ 9867ab160eSEdward Cree EFX_TC_PRIO__NUM 9967ab160eSEdward Cree }; 10067ab160eSEdward Cree 10167ab160eSEdward Cree /** 10267ab160eSEdward Cree * struct efx_tc_state - control plane data for TC offload 10367ab160eSEdward Cree * 1047ce3e235SEdward Cree * @caps: MAE capabilities reported by MCDI 1059dc0cad2SEdward Cree * @block_list: List of &struct efx_tc_block_binding 106f54a28a2SEdward Cree * @mutex: Used to serialise operations on TC hashtables 10719a0c989SEdward Cree * @counter_ht: Hashtable of TC counters (FW IDs and counter values) 10819a0c989SEdward Cree * @counter_id_ht: Hashtable mapping TC counter cookies to counters 109f54a28a2SEdward Cree * @match_action_ht: Hashtable of TC match-action rules 110e37f3b15SEdward Cree * @reps_mport_id: MAE port allocated for representor RX 111e37f3b15SEdward Cree * @reps_filter_uc: VNIC filter for representor unicast RX (promisc) 112e37f3b15SEdward Cree * @reps_filter_mc: VNIC filter for representor multicast RX (allmulti) 113e37f3b15SEdward Cree * @reps_mport_vport_id: vport_id for representor RX filters 114e5731274SEdward Cree * @flush_counters: counters have been stopped, waiting for drain 115e5731274SEdward Cree * @flush_gen: final generation count per type array as reported by 116e5731274SEdward Cree * MC_CMD_MAE_COUNTERS_STREAM_STOP 117e5731274SEdward Cree * @seen_gen: most recent generation count per type as seen by efx_tc_rx() 118e5731274SEdward Cree * @flush_wq: wait queue used by efx_mae_stop_counters() to wait for 119e5731274SEdward Cree * MAE counters RXQ to finish draining 12067ab160eSEdward Cree * @dflt: Match-action rules for default switching; at priority 12167ab160eSEdward Cree * %EFX_TC_PRIO_DFLT. Named by *ingress* port 12267ab160eSEdward Cree * @dflt.pf: rule for traffic ingressing from PF (egresses to wire) 12367ab160eSEdward Cree * @dflt.wire: rule for traffic ingressing from wire (egresses to PF) 1249dc0cad2SEdward Cree * @up: have TC datastructures been set up? 12567ab160eSEdward Cree */ 12667ab160eSEdward Cree struct efx_tc_state { 1277ce3e235SEdward Cree struct mae_caps *caps; 1289dc0cad2SEdward Cree struct list_head block_list; 129f54a28a2SEdward Cree struct mutex mutex; 13019a0c989SEdward Cree struct rhashtable counter_ht; 13119a0c989SEdward Cree struct rhashtable counter_id_ht; 132f54a28a2SEdward Cree struct rhashtable match_action_ht; 133e37f3b15SEdward Cree u32 reps_mport_id, reps_mport_vport_id; 134e37f3b15SEdward Cree s32 reps_filter_uc, reps_filter_mc; 135e5731274SEdward Cree bool flush_counters; 136e5731274SEdward Cree u32 flush_gen[EFX_TC_COUNTER_TYPE_MAX]; 137e5731274SEdward Cree u32 seen_gen[EFX_TC_COUNTER_TYPE_MAX]; 138e5731274SEdward Cree wait_queue_head_t flush_wq; 13967ab160eSEdward Cree struct { 14067ab160eSEdward Cree struct efx_tc_flow_rule pf; 14167ab160eSEdward Cree struct efx_tc_flow_rule wire; 14267ab160eSEdward Cree } dflt; 1439dc0cad2SEdward Cree bool up; 14467ab160eSEdward Cree }; 14567ab160eSEdward Cree 14667ab160eSEdward Cree struct efx_rep; 14767ab160eSEdward Cree 14867ab160eSEdward Cree int efx_tc_configure_default_rule_rep(struct efx_rep *efv); 14967ab160eSEdward Cree void efx_tc_deconfigure_default_rule(struct efx_nic *efx, 15067ab160eSEdward Cree struct efx_tc_flow_rule *rule); 1519dc0cad2SEdward Cree int efx_tc_flower(struct efx_nic *efx, struct net_device *net_dev, 1529dc0cad2SEdward Cree struct flow_cls_offload *tc, struct efx_rep *efv); 15367ab160eSEdward Cree 154e37f3b15SEdward Cree int efx_tc_insert_rep_filters(struct efx_nic *efx); 155e37f3b15SEdward Cree void efx_tc_remove_rep_filters(struct efx_nic *efx); 156e37f3b15SEdward Cree 15767ab160eSEdward Cree int efx_init_tc(struct efx_nic *efx); 15867ab160eSEdward Cree void efx_fini_tc(struct efx_nic *efx); 15967ab160eSEdward Cree 16067ab160eSEdward Cree int efx_init_struct_tc(struct efx_nic *efx); 16167ab160eSEdward Cree void efx_fini_struct_tc(struct efx_nic *efx); 16267ab160eSEdward Cree 16367ab160eSEdward Cree #endif /* EFX_TC_H */ 164