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