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