Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 | /* Broadcom NetXtreme-C/E network driver. * * Copyright (c) 2017 Broadcom Limited * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation. */ #ifndef BNXT_TC_H #define BNXT_TC_H #ifdef CONFIG_BNXT_FLOWER_OFFLOAD #include <net/ip_tunnels.h> /* Structs used for storing the filter/actions of the TC cmd. */ struct bnxt_tc_l2_key { u8 dmac[ETH_ALEN]; u8 smac[ETH_ALEN]; __be16 inner_vlan_tpid; __be16 inner_vlan_tci; __be16 ether_type; u8 num_vlans; u8 dir; #define BNXT_DIR_RX 1 #define BNXT_DIR_TX 0 }; struct bnxt_tc_l3_key { union { struct { struct in_addr daddr; struct in_addr saddr; } ipv4; struct { struct in6_addr daddr; struct in6_addr saddr; } ipv6; }; }; struct bnxt_tc_l4_key { u8 ip_proto; union { struct { __be16 sport; __be16 dport; } ports; struct { u8 type; u8 code; } icmp; }; }; struct bnxt_tc_tunnel_key { struct bnxt_tc_l2_key l2; struct bnxt_tc_l3_key l3; struct bnxt_tc_l4_key l4; __be32 id; }; #define bnxt_eth_addr_key_mask_invalid(eth_addr, eth_addr_mask) \ ((is_wildcard(&(eth_addr)[0], ETH_ALEN) && \ is_wildcard(&(eth_addr)[ETH_ALEN / 2], ETH_ALEN)) || \ (is_wildcard(&(eth_addr_mask)[0], ETH_ALEN) && \ is_wildcard(&(eth_addr_mask)[ETH_ALEN / 2], ETH_ALEN))) struct bnxt_tc_actions { u32 flags; #define BNXT_TC_ACTION_FLAG_FWD BIT(0) #define BNXT_TC_ACTION_FLAG_FWD_VXLAN BIT(1) #define BNXT_TC_ACTION_FLAG_PUSH_VLAN BIT(3) #define BNXT_TC_ACTION_FLAG_POP_VLAN BIT(4) #define BNXT_TC_ACTION_FLAG_DROP BIT(5) #define BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP BIT(6) #define BNXT_TC_ACTION_FLAG_TUNNEL_DECAP BIT(7) #define BNXT_TC_ACTION_FLAG_L2_REWRITE BIT(8) #define BNXT_TC_ACTION_FLAG_NAT_XLATE BIT(9) u16 dst_fid; struct net_device *dst_dev; __be16 push_vlan_tpid; __be16 push_vlan_tci; /* tunnel encap */ struct ip_tunnel_key tun_encap_key; #define PEDIT_OFFSET_SMAC_LAST_4_BYTES 0x8 __be16 l2_rewrite_dmac[3]; __be16 l2_rewrite_smac[3]; struct { bool src_xlate; /* true => translate src, * false => translate dst * Mutually exclusive, i.e cannot set both */ bool l3_is_ipv4; /* false means L3 is ipv6 */ struct bnxt_tc_l3_key l3; struct bnxt_tc_l4_key l4; } nat; }; struct bnxt_tc_flow { u32 flags; #define BNXT_TC_FLOW_FLAGS_ETH_ADDRS BIT(1) #define BNXT_TC_FLOW_FLAGS_IPV4_ADDRS BIT(2) #define BNXT_TC_FLOW_FLAGS_IPV6_ADDRS BIT(3) #define BNXT_TC_FLOW_FLAGS_PORTS BIT(4) #define BNXT_TC_FLOW_FLAGS_ICMP BIT(5) #define BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS BIT(6) #define BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS BIT(7) #define BNXT_TC_FLOW_FLAGS_TUNL_IPV6_ADDRS BIT(8) #define BNXT_TC_FLOW_FLAGS_TUNL_PORTS BIT(9) #define BNXT_TC_FLOW_FLAGS_TUNL_ID BIT(10) #define BNXT_TC_FLOW_FLAGS_TUNNEL (BNXT_TC_FLOW_FLAGS_TUNL_ETH_ADDRS | \ BNXT_TC_FLOW_FLAGS_TUNL_IPV4_ADDRS | \ BNXT_TC_FLOW_FLAGS_TUNL_IPV6_ADDRS |\ BNXT_TC_FLOW_FLAGS_TUNL_PORTS |\ BNXT_TC_FLOW_FLAGS_TUNL_ID) /* flow applicable to pkts ingressing on this fid */ u16 src_fid; struct bnxt_tc_l2_key l2_key; struct bnxt_tc_l2_key l2_mask; struct bnxt_tc_l3_key l3_key; struct bnxt_tc_l3_key l3_mask; struct bnxt_tc_l4_key l4_key; struct bnxt_tc_l4_key l4_mask; struct ip_tunnel_key tun_key; struct ip_tunnel_key tun_mask; struct bnxt_tc_actions actions; /* updated stats accounting for hw-counter wrap-around */ struct bnxt_tc_flow_stats stats; /* previous snap-shot of stats */ struct bnxt_tc_flow_stats prev_stats; unsigned long lastused; /* jiffies */ /* for calculating delta from prev_stats and * updating prev_stats atomically. */ spinlock_t stats_lock; }; /* Tunnel encap/decap hash table * This table is used to maintain a list of flows that use * the same tunnel encap/decap params (ip_daddrs, vni, udp_dport) * and the FW returned handle. * A separate table is maintained for encap and decap */ struct bnxt_tc_tunnel_node { struct ip_tunnel_key key; struct rhash_head node; /* tunnel l2 info */ struct bnxt_tc_l2_key l2_info; #define INVALID_TUNNEL_HANDLE cpu_to_le32(0xffffffff) /* tunnel handle returned by FW */ __le32 tunnel_handle; u32 refcount; struct rcu_head rcu; }; /* L2 hash table * The same data-struct is used for L2-flow table and L2-tunnel table. * The L2 part of a flow or tunnel is stored in a hash table. * A flow that shares the same L2 key/mask with an * already existing flow/tunnel must refer to it's flow handle or * decap_filter_id respectively. */ struct bnxt_tc_l2_node { /* hash key: first 16b of key */ #define BNXT_TC_L2_KEY_LEN 16 struct bnxt_tc_l2_key key; struct rhash_head node; /* a linked list of flows that share the same l2 key */ struct list_head common_l2_flows; /* number of flows/tunnels sharing the l2 key */ u16 refcount; struct rcu_head rcu; }; struct bnxt_tc_flow_node { /* hash key: provided by TC */ unsigned long cookie; struct rhash_head node; struct bnxt_tc_flow flow; __le64 ext_flow_handle; __le16 flow_handle; __le32 flow_id; /* L2 node in l2 hashtable that shares flow's l2 key */ struct bnxt_tc_l2_node *l2_node; /* for the shared_flows list maintained in l2_node */ struct list_head l2_list_node; /* tunnel encap related */ struct bnxt_tc_tunnel_node *encap_node; /* tunnel decap related */ struct bnxt_tc_tunnel_node *decap_node; /* L2 node in tunnel-l2 hashtable that shares flow's tunnel l2 key */ struct bnxt_tc_l2_node *decap_l2_node; /* for the shared_flows list maintained in tunnel decap l2_node */ struct list_head decap_l2_list_node; struct rcu_head rcu; }; int bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid, struct flow_cls_offload *cls_flower); int bnxt_init_tc(struct bnxt *bp); void bnxt_shutdown_tc(struct bnxt *bp); void bnxt_tc_flow_stats_work(struct bnxt *bp); static inline bool bnxt_tc_flower_enabled(struct bnxt *bp) { return bp->tc_info && bp->tc_info->enabled; } #else /* CONFIG_BNXT_FLOWER_OFFLOAD */ static inline int bnxt_tc_setup_flower(struct bnxt *bp, u16 src_fid, struct flow_cls_offload *cls_flower) { return -EOPNOTSUPP; } static inline int bnxt_init_tc(struct bnxt *bp) { return 0; } static inline void bnxt_shutdown_tc(struct bnxt *bp) { } static inline void bnxt_tc_flow_stats_work(struct bnxt *bp) { } static inline bool bnxt_tc_flower_enabled(struct bnxt *bp) { return false; } #endif /* CONFIG_BNXT_FLOWER_OFFLOAD */ #endif /* BNXT_TC_H */ |