]>
Commit | Line | Data |
---|---|---|
64eebcfd | 1 | /**************************************************************************** |
f7a6d2c4 BH |
2 | * Driver for Solarflare network controllers and boards |
3 | * Copyright 2005-2013 Solarflare Communications Inc. | |
64eebcfd BH |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify it | |
6 | * under the terms of the GNU General Public License version 2 as published | |
7 | * by the Free Software Foundation, incorporated herein by reference. | |
8 | */ | |
9 | ||
10 | #ifndef EFX_FILTER_H | |
11 | #define EFX_FILTER_H | |
12 | ||
13 | #include <linux/types.h> | |
7c460d9b BH |
14 | #include <linux/if_ether.h> |
15 | #include <asm/byteorder.h> | |
64eebcfd | 16 | |
64eebcfd | 17 | /** |
7c460d9b BH |
18 | * enum efx_filter_match_flags - Flags for hardware filter match type |
19 | * @EFX_FILTER_MATCH_REM_HOST: Match by remote IP host address | |
20 | * @EFX_FILTER_MATCH_LOC_HOST: Match by local IP host address | |
21 | * @EFX_FILTER_MATCH_REM_MAC: Match by remote MAC address | |
22 | * @EFX_FILTER_MATCH_REM_PORT: Match by remote TCP/UDP port | |
23 | * @EFX_FILTER_MATCH_LOC_MAC: Match by local MAC address | |
24 | * @EFX_FILTER_MATCH_LOC_PORT: Match by local TCP/UDP port | |
25 | * @EFX_FILTER_MATCH_ETHER_TYPE: Match by Ether-type | |
26 | * @EFX_FILTER_MATCH_INNER_VID: Match by inner VLAN ID | |
27 | * @EFX_FILTER_MATCH_OUTER_VID: Match by outer VLAN ID | |
28 | * @EFX_FILTER_MATCH_IP_PROTO: Match by IP transport protocol | |
29 | * @EFX_FILTER_MATCH_LOC_MAC_IG: Match by local MAC address I/G bit. | |
9b410801 | 30 | * @EFX_FILTER_MATCH_ENCAP_TYPE: Match by encapsulation type. |
7c460d9b | 31 | * Used for RX default unicast and multicast/broadcast filters. |
64eebcfd | 32 | * |
7c460d9b BH |
33 | * Only some combinations are supported, depending on NIC type: |
34 | * | |
35 | * - Falcon supports RX filters matching by {TCP,UDP}/IPv4 4-tuple or | |
36 | * local 2-tuple (only implemented for Falcon B0) | |
37 | * | |
38 | * - Siena supports RX and TX filters matching by {TCP,UDP}/IPv4 4-tuple | |
39 | * or local 2-tuple, or local MAC with or without outer VID, and RX | |
40 | * default filters | |
41 | * | |
42 | * - Huntington supports filter matching controlled by firmware, potentially | |
43 | * using {TCP,UDP}/IPv{4,6} 4-tuple or local 2-tuple, local MAC or I/G bit, | |
44 | * with or without outer and inner VID | |
64eebcfd | 45 | */ |
7c460d9b BH |
46 | enum efx_filter_match_flags { |
47 | EFX_FILTER_MATCH_REM_HOST = 0x0001, | |
48 | EFX_FILTER_MATCH_LOC_HOST = 0x0002, | |
49 | EFX_FILTER_MATCH_REM_MAC = 0x0004, | |
50 | EFX_FILTER_MATCH_REM_PORT = 0x0008, | |
51 | EFX_FILTER_MATCH_LOC_MAC = 0x0010, | |
52 | EFX_FILTER_MATCH_LOC_PORT = 0x0020, | |
53 | EFX_FILTER_MATCH_ETHER_TYPE = 0x0040, | |
54 | EFX_FILTER_MATCH_INNER_VID = 0x0080, | |
55 | EFX_FILTER_MATCH_OUTER_VID = 0x0100, | |
56 | EFX_FILTER_MATCH_IP_PROTO = 0x0200, | |
57 | EFX_FILTER_MATCH_LOC_MAC_IG = 0x0400, | |
9b410801 | 58 | EFX_FILTER_MATCH_ENCAP_TYPE = 0x0800, |
64eebcfd BH |
59 | }; |
60 | ||
61 | /** | |
62 | * enum efx_filter_priority - priority of a hardware filter specification | |
63 | * @EFX_FILTER_PRI_HINT: Performance hint | |
7665d1ab BH |
64 | * @EFX_FILTER_PRI_AUTO: Automatic filter based on device address list |
65 | * or hardware requirements. This may only be used by the filter | |
66 | * implementation for each NIC type. | |
64eebcfd | 67 | * @EFX_FILTER_PRI_MANUAL: Manually configured filter |
3d885e39 BH |
68 | * @EFX_FILTER_PRI_REQUIRED: Required for correct behaviour (user-level |
69 | * networking and SR-IOV) | |
64eebcfd BH |
70 | */ |
71 | enum efx_filter_priority { | |
72 | EFX_FILTER_PRI_HINT = 0, | |
7665d1ab | 73 | EFX_FILTER_PRI_AUTO, |
64eebcfd BH |
74 | EFX_FILTER_PRI_MANUAL, |
75 | EFX_FILTER_PRI_REQUIRED, | |
76 | }; | |
77 | ||
78 | /** | |
79 | * enum efx_filter_flags - flags for hardware filter specifications | |
80 | * @EFX_FILTER_FLAG_RX_RSS: Use RSS to spread across multiple queues. | |
81 | * By default, matching packets will be delivered only to the | |
82 | * specified queue. If this flag is set, they will be delivered | |
83 | * to a range of queues offset from the specified queue number | |
84 | * according to the indirection table. | |
85 | * @EFX_FILTER_FLAG_RX_SCATTER: Enable DMA scatter on the receiving | |
86 | * queue. | |
7665d1ab BH |
87 | * @EFX_FILTER_FLAG_RX_OVER_AUTO: Indicates a filter that is |
88 | * overriding an automatic filter (priority | |
89 | * %EFX_FILTER_PRI_AUTO). This may only be set by the filter | |
90 | * implementation for each type. A removal request will restore | |
91 | * the automatic filter in its place. | |
c39d35eb | 92 | * @EFX_FILTER_FLAG_RX: Filter is for RX |
3d885e39 | 93 | * @EFX_FILTER_FLAG_TX: Filter is for TX |
64eebcfd BH |
94 | */ |
95 | enum efx_filter_flags { | |
96 | EFX_FILTER_FLAG_RX_RSS = 0x01, | |
97 | EFX_FILTER_FLAG_RX_SCATTER = 0x02, | |
7665d1ab | 98 | EFX_FILTER_FLAG_RX_OVER_AUTO = 0x04, |
c39d35eb | 99 | EFX_FILTER_FLAG_RX = 0x08, |
3d885e39 | 100 | EFX_FILTER_FLAG_TX = 0x10, |
64eebcfd BH |
101 | }; |
102 | ||
9b410801 EC |
103 | /** enum efx_encap_type - types of encapsulation |
104 | * @EFX_ENCAP_TYPE_NONE: no encapsulation | |
105 | * @EFX_ENCAP_TYPE_VXLAN: VXLAN encapsulation | |
106 | * @EFX_ENCAP_TYPE_NVGRE: NVGRE encapsulation | |
107 | * @EFX_ENCAP_TYPE_GENEVE: GENEVE encapsulation | |
108 | * @EFX_ENCAP_FLAG_IPV6: indicates IPv6 outer frame | |
109 | * | |
110 | * Contains both enumerated types and flags. | |
111 | * To get just the type, OR with @EFX_ENCAP_TYPES_MASK. | |
112 | */ | |
113 | enum efx_encap_type { | |
114 | EFX_ENCAP_TYPE_NONE = 0, | |
115 | EFX_ENCAP_TYPE_VXLAN = 1, | |
116 | EFX_ENCAP_TYPE_NVGRE = 2, | |
117 | EFX_ENCAP_TYPE_GENEVE = 3, | |
118 | ||
119 | EFX_ENCAP_TYPES_MASK = 7, | |
120 | EFX_ENCAP_FLAG_IPV6 = 8, | |
121 | }; | |
122 | ||
64eebcfd BH |
123 | /** |
124 | * struct efx_filter_spec - specification for a hardware filter | |
7c460d9b | 125 | * @match_flags: Match type flags, from &enum efx_filter_match_flags |
64eebcfd BH |
126 | * @priority: Priority of the filter, from &enum efx_filter_priority |
127 | * @flags: Miscellaneous flags, from &enum efx_filter_flags | |
7c460d9b | 128 | * @rss_context: RSS context to use, if %EFX_FILTER_FLAG_RX_RSS is set |
f26e958c BH |
129 | * @dmaq_id: Source/target queue index, or %EFX_FILTER_RX_DMAQ_ID_DROP for |
130 | * an RX drop filter | |
7c460d9b BH |
131 | * @outer_vid: Outer VLAN ID to match, if %EFX_FILTER_MATCH_OUTER_VID is set |
132 | * @inner_vid: Inner VLAN ID to match, if %EFX_FILTER_MATCH_INNER_VID is set | |
133 | * @loc_mac: Local MAC address to match, if %EFX_FILTER_MATCH_LOC_MAC or | |
134 | * %EFX_FILTER_MATCH_LOC_MAC_IG is set | |
135 | * @rem_mac: Remote MAC address to match, if %EFX_FILTER_MATCH_REM_MAC is set | |
136 | * @ether_type: Ether-type to match, if %EFX_FILTER_MATCH_ETHER_TYPE is set | |
137 | * @ip_proto: IP transport protocol to match, if %EFX_FILTER_MATCH_IP_PROTO | |
138 | * is set | |
139 | * @loc_host: Local IP host to match, if %EFX_FILTER_MATCH_LOC_HOST is set | |
140 | * @rem_host: Remote IP host to match, if %EFX_FILTER_MATCH_REM_HOST is set | |
141 | * @loc_port: Local TCP/UDP port to match, if %EFX_FILTER_MATCH_LOC_PORT is set | |
142 | * @rem_port: Remote TCP/UDP port to match, if %EFX_FILTER_MATCH_REM_PORT is set | |
9b410801 EC |
143 | * @encap_type: Encapsulation type to match (from &enum efx_encap_type), if |
144 | * %EFX_FILTER_MATCH_ENCAP_TYPE is set | |
64eebcfd | 145 | * |
7c460d9b BH |
146 | * The efx_filter_init_rx() or efx_filter_init_tx() function *must* be |
147 | * used to initialise the structure. The efx_filter_set_*() functions | |
148 | * may then be used to set @rss_context, @match_flags and related | |
149 | * fields. | |
b1f9284b BH |
150 | * |
151 | * The @priority field is used by software to determine whether a new | |
152 | * filter may replace an old one. The hardware priority of a filter | |
7c460d9b | 153 | * depends on which fields are matched. |
64eebcfd BH |
154 | */ |
155 | struct efx_filter_spec { | |
7c460d9b BH |
156 | u32 match_flags:12; |
157 | u32 priority:2; | |
158 | u32 flags:6; | |
159 | u32 dmaq_id:12; | |
160 | u32 rss_context; | |
161 | __be16 outer_vid __aligned(4); /* allow jhash2() of match values */ | |
162 | __be16 inner_vid; | |
163 | u8 loc_mac[ETH_ALEN]; | |
164 | u8 rem_mac[ETH_ALEN]; | |
165 | __be16 ether_type; | |
166 | u8 ip_proto; | |
167 | __be32 loc_host[4]; | |
168 | __be32 rem_host[4]; | |
169 | __be16 loc_port; | |
170 | __be16 rem_port; | |
9b410801 EC |
171 | u32 encap_type:4; |
172 | /* total 65 bytes */ | |
64eebcfd BH |
173 | }; |
174 | ||
f26e958c | 175 | enum { |
7c460d9b | 176 | EFX_FILTER_RSS_CONTEXT_DEFAULT = 0xffffffff, |
f26e958c BH |
177 | EFX_FILTER_RX_DMAQ_ID_DROP = 0xfff |
178 | }; | |
179 | ||
c39d35eb BH |
180 | static inline void efx_filter_init_rx(struct efx_filter_spec *spec, |
181 | enum efx_filter_priority priority, | |
182 | enum efx_filter_flags flags, | |
183 | unsigned rxq_id) | |
64eebcfd | 184 | { |
7c460d9b | 185 | memset(spec, 0, sizeof(*spec)); |
c39d35eb BH |
186 | spec->priority = priority; |
187 | spec->flags = EFX_FILTER_FLAG_RX | flags; | |
7c460d9b | 188 | spec->rss_context = EFX_FILTER_RSS_CONTEXT_DEFAULT; |
c39d35eb | 189 | spec->dmaq_id = rxq_id; |
64eebcfd BH |
190 | } |
191 | ||
3d885e39 BH |
192 | static inline void efx_filter_init_tx(struct efx_filter_spec *spec, |
193 | unsigned txq_id) | |
194 | { | |
7c460d9b | 195 | memset(spec, 0, sizeof(*spec)); |
3d885e39 BH |
196 | spec->priority = EFX_FILTER_PRI_REQUIRED; |
197 | spec->flags = EFX_FILTER_FLAG_TX; | |
198 | spec->dmaq_id = txq_id; | |
199 | } | |
200 | ||
7c460d9b BH |
201 | /** |
202 | * efx_filter_set_ipv4_local - specify IPv4 host, transport protocol and port | |
203 | * @spec: Specification to initialise | |
204 | * @proto: Transport layer protocol number | |
205 | * @host: Local host address (network byte order) | |
206 | * @port: Local port (network byte order) | |
207 | */ | |
208 | static inline int | |
209 | efx_filter_set_ipv4_local(struct efx_filter_spec *spec, u8 proto, | |
210 | __be32 host, __be16 port) | |
211 | { | |
212 | spec->match_flags |= | |
213 | EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO | | |
214 | EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT; | |
215 | spec->ether_type = htons(ETH_P_IP); | |
216 | spec->ip_proto = proto; | |
217 | spec->loc_host[0] = host; | |
218 | spec->loc_port = port; | |
219 | return 0; | |
220 | } | |
221 | ||
222 | /** | |
223 | * efx_filter_set_ipv4_full - specify IPv4 hosts, transport protocol and ports | |
224 | * @spec: Specification to initialise | |
225 | * @proto: Transport layer protocol number | |
226 | * @lhost: Local host address (network byte order) | |
227 | * @lport: Local port (network byte order) | |
228 | * @rhost: Remote host address (network byte order) | |
229 | * @rport: Remote port (network byte order) | |
230 | */ | |
231 | static inline int | |
232 | efx_filter_set_ipv4_full(struct efx_filter_spec *spec, u8 proto, | |
233 | __be32 lhost, __be16 lport, | |
234 | __be32 rhost, __be16 rport) | |
235 | { | |
236 | spec->match_flags |= | |
237 | EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO | | |
238 | EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT | | |
239 | EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT; | |
240 | spec->ether_type = htons(ETH_P_IP); | |
241 | spec->ip_proto = proto; | |
242 | spec->loc_host[0] = lhost; | |
243 | spec->loc_port = lport; | |
244 | spec->rem_host[0] = rhost; | |
245 | spec->rem_port = rport; | |
246 | return 0; | |
247 | } | |
248 | ||
c39d35eb BH |
249 | enum { |
250 | EFX_FILTER_VID_UNSPEC = 0xffff, | |
251 | }; | |
64eebcfd | 252 | |
7c460d9b BH |
253 | /** |
254 | * efx_filter_set_eth_local - specify local Ethernet address and/or VID | |
255 | * @spec: Specification to initialise | |
256 | * @vid: Outer VLAN ID to match, or %EFX_FILTER_VID_UNSPEC | |
257 | * @addr: Local Ethernet MAC address, or %NULL | |
258 | */ | |
259 | static inline int efx_filter_set_eth_local(struct efx_filter_spec *spec, | |
260 | u16 vid, const u8 *addr) | |
261 | { | |
262 | if (vid == EFX_FILTER_VID_UNSPEC && addr == NULL) | |
263 | return -EINVAL; | |
264 | ||
265 | if (vid != EFX_FILTER_VID_UNSPEC) { | |
266 | spec->match_flags |= EFX_FILTER_MATCH_OUTER_VID; | |
267 | spec->outer_vid = htons(vid); | |
268 | } | |
269 | if (addr != NULL) { | |
270 | spec->match_flags |= EFX_FILTER_MATCH_LOC_MAC; | |
cd84ff4d | 271 | ether_addr_copy(spec->loc_mac, addr); |
7c460d9b BH |
272 | } |
273 | return 0; | |
274 | } | |
275 | ||
276 | /** | |
277 | * efx_filter_set_uc_def - specify matching otherwise-unmatched unicast | |
278 | * @spec: Specification to initialise | |
279 | */ | |
280 | static inline int efx_filter_set_uc_def(struct efx_filter_spec *spec) | |
281 | { | |
282 | spec->match_flags |= EFX_FILTER_MATCH_LOC_MAC_IG; | |
283 | return 0; | |
284 | } | |
285 | ||
286 | /** | |
287 | * efx_filter_set_mc_def - specify matching otherwise-unmatched multicast | |
288 | * @spec: Specification to initialise | |
289 | */ | |
290 | static inline int efx_filter_set_mc_def(struct efx_filter_spec *spec) | |
291 | { | |
292 | spec->match_flags |= EFX_FILTER_MATCH_LOC_MAC_IG; | |
293 | spec->loc_mac[0] = 1; | |
294 | return 0; | |
295 | } | |
296 | ||
9b410801 EC |
297 | static inline void efx_filter_set_encap_type(struct efx_filter_spec *spec, |
298 | enum efx_encap_type encap_type) | |
299 | { | |
300 | spec->match_flags |= EFX_FILTER_MATCH_ENCAP_TYPE; | |
301 | spec->encap_type = encap_type; | |
302 | } | |
303 | ||
304 | static inline enum efx_encap_type efx_filter_get_encap_type( | |
305 | const struct efx_filter_spec *spec) | |
306 | { | |
307 | if (spec->match_flags & EFX_FILTER_MATCH_ENCAP_TYPE) | |
308 | return spec->encap_type; | |
309 | return EFX_ENCAP_TYPE_NONE; | |
310 | } | |
64eebcfd | 311 | #endif /* EFX_FILTER_H */ |