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