1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /**************************************************************************** |
3 | * Driver for Solarflare network controllers and boards |
4 | * Copyright 2005-2013 Solarflare Communications Inc. |
5 | */ |
6 | |
7 | #ifndef EF4_FILTER_H |
8 | #define EF4_FILTER_H |
9 | |
10 | #include <linux/types.h> |
11 | #include <linux/if_ether.h> |
12 | #include <asm/byteorder.h> |
13 | |
14 | /** |
15 | * enum ef4_filter_match_flags - Flags for hardware filter match type |
16 | * @EF4_FILTER_MATCH_REM_HOST: Match by remote IP host address |
17 | * @EF4_FILTER_MATCH_LOC_HOST: Match by local IP host address |
18 | * @EF4_FILTER_MATCH_REM_MAC: Match by remote MAC address |
19 | * @EF4_FILTER_MATCH_REM_PORT: Match by remote TCP/UDP port |
20 | * @EF4_FILTER_MATCH_LOC_MAC: Match by local MAC address |
21 | * @EF4_FILTER_MATCH_LOC_PORT: Match by local TCP/UDP port |
22 | * @EF4_FILTER_MATCH_ETHER_TYPE: Match by Ether-type |
23 | * @EF4_FILTER_MATCH_INNER_VID: Match by inner VLAN ID |
24 | * @EF4_FILTER_MATCH_OUTER_VID: Match by outer VLAN ID |
25 | * @EF4_FILTER_MATCH_IP_PROTO: Match by IP transport protocol |
26 | * @EF4_FILTER_MATCH_LOC_MAC_IG: Match by local MAC address I/G bit. |
27 | * Used for RX default unicast and multicast/broadcast filters. |
28 | * |
29 | * Only some combinations are supported, depending on NIC type: |
30 | * |
31 | * - Falcon supports RX filters matching by {TCP,UDP}/IPv4 4-tuple or |
32 | * local 2-tuple (only implemented for Falcon B0) |
33 | * |
34 | * - Siena supports RX and TX filters matching by {TCP,UDP}/IPv4 4-tuple |
35 | * or local 2-tuple, or local MAC with or without outer VID, and RX |
36 | * default filters |
37 | * |
38 | * - Huntington supports filter matching controlled by firmware, potentially |
39 | * using {TCP,UDP}/IPv{4,6} 4-tuple or local 2-tuple, local MAC or I/G bit, |
40 | * with or without outer and inner VID |
41 | */ |
42 | enum ef4_filter_match_flags { |
43 | EF4_FILTER_MATCH_REM_HOST = 0x0001, |
44 | EF4_FILTER_MATCH_LOC_HOST = 0x0002, |
45 | EF4_FILTER_MATCH_REM_MAC = 0x0004, |
46 | EF4_FILTER_MATCH_REM_PORT = 0x0008, |
47 | EF4_FILTER_MATCH_LOC_MAC = 0x0010, |
48 | EF4_FILTER_MATCH_LOC_PORT = 0x0020, |
49 | EF4_FILTER_MATCH_ETHER_TYPE = 0x0040, |
50 | EF4_FILTER_MATCH_INNER_VID = 0x0080, |
51 | EF4_FILTER_MATCH_OUTER_VID = 0x0100, |
52 | EF4_FILTER_MATCH_IP_PROTO = 0x0200, |
53 | EF4_FILTER_MATCH_LOC_MAC_IG = 0x0400, |
54 | }; |
55 | |
56 | /** |
57 | * enum ef4_filter_priority - priority of a hardware filter specification |
58 | * @EF4_FILTER_PRI_HINT: Performance hint |
59 | * @EF4_FILTER_PRI_AUTO: Automatic filter based on device address list |
60 | * or hardware requirements. This may only be used by the filter |
61 | * implementation for each NIC type. |
62 | * @EF4_FILTER_PRI_MANUAL: Manually configured filter |
63 | * @EF4_FILTER_PRI_REQUIRED: Required for correct behaviour (user-level |
64 | * networking and SR-IOV) |
65 | */ |
66 | enum ef4_filter_priority { |
67 | EF4_FILTER_PRI_HINT = 0, |
68 | EF4_FILTER_PRI_AUTO, |
69 | EF4_FILTER_PRI_MANUAL, |
70 | EF4_FILTER_PRI_REQUIRED, |
71 | }; |
72 | |
73 | /** |
74 | * enum ef4_filter_flags - flags for hardware filter specifications |
75 | * @EF4_FILTER_FLAG_RX_RSS: Use RSS to spread across multiple queues. |
76 | * By default, matching packets will be delivered only to the |
77 | * specified queue. If this flag is set, they will be delivered |
78 | * to a range of queues offset from the specified queue number |
79 | * according to the indirection table. |
80 | * @EF4_FILTER_FLAG_RX_SCATTER: Enable DMA scatter on the receiving |
81 | * queue. |
82 | * @EF4_FILTER_FLAG_RX_OVER_AUTO: Indicates a filter that is |
83 | * overriding an automatic filter (priority |
84 | * %EF4_FILTER_PRI_AUTO). This may only be set by the filter |
85 | * implementation for each type. A removal request will restore |
86 | * the automatic filter in its place. |
87 | * @EF4_FILTER_FLAG_RX: Filter is for RX |
88 | * @EF4_FILTER_FLAG_TX: Filter is for TX |
89 | */ |
90 | enum ef4_filter_flags { |
91 | = 0x01, |
92 | EF4_FILTER_FLAG_RX_SCATTER = 0x02, |
93 | EF4_FILTER_FLAG_RX_OVER_AUTO = 0x04, |
94 | EF4_FILTER_FLAG_RX = 0x08, |
95 | EF4_FILTER_FLAG_TX = 0x10, |
96 | }; |
97 | |
98 | /** |
99 | * struct ef4_filter_spec - specification for a hardware filter |
100 | * @match_flags: Match type flags, from &enum ef4_filter_match_flags |
101 | * @priority: Priority of the filter, from &enum ef4_filter_priority |
102 | * @flags: Miscellaneous flags, from &enum ef4_filter_flags |
103 | * @rss_context: RSS context to use, if %EF4_FILTER_FLAG_RX_RSS is set |
104 | * @dmaq_id: Source/target queue index, or %EF4_FILTER_RX_DMAQ_ID_DROP for |
105 | * an RX drop filter |
106 | * @outer_vid: Outer VLAN ID to match, if %EF4_FILTER_MATCH_OUTER_VID is set |
107 | * @inner_vid: Inner VLAN ID to match, if %EF4_FILTER_MATCH_INNER_VID is set |
108 | * @loc_mac: Local MAC address to match, if %EF4_FILTER_MATCH_LOC_MAC or |
109 | * %EF4_FILTER_MATCH_LOC_MAC_IG is set |
110 | * @rem_mac: Remote MAC address to match, if %EF4_FILTER_MATCH_REM_MAC is set |
111 | * @ether_type: Ether-type to match, if %EF4_FILTER_MATCH_ETHER_TYPE is set |
112 | * @ip_proto: IP transport protocol to match, if %EF4_FILTER_MATCH_IP_PROTO |
113 | * is set |
114 | * @loc_host: Local IP host to match, if %EF4_FILTER_MATCH_LOC_HOST is set |
115 | * @rem_host: Remote IP host to match, if %EF4_FILTER_MATCH_REM_HOST is set |
116 | * @loc_port: Local TCP/UDP port to match, if %EF4_FILTER_MATCH_LOC_PORT is set |
117 | * @rem_port: Remote TCP/UDP port to match, if %EF4_FILTER_MATCH_REM_PORT is set |
118 | * |
119 | * The ef4_filter_init_rx() or ef4_filter_init_tx() function *must* be |
120 | * used to initialise the structure. The ef4_filter_set_*() functions |
121 | * may then be used to set @rss_context, @match_flags and related |
122 | * fields. |
123 | * |
124 | * The @priority field is used by software to determine whether a new |
125 | * filter may replace an old one. The hardware priority of a filter |
126 | * depends on which fields are matched. |
127 | */ |
128 | struct ef4_filter_spec { |
129 | u32 match_flags:12; |
130 | u32 priority:2; |
131 | u32 flags:6; |
132 | u32 dmaq_id:12; |
133 | u32 ; |
134 | __be16 outer_vid __aligned(4); /* allow jhash2() of match values */ |
135 | __be16 inner_vid; |
136 | u8 loc_mac[ETH_ALEN]; |
137 | u8 rem_mac[ETH_ALEN]; |
138 | __be16 ether_type; |
139 | u8 ip_proto; |
140 | __be32 loc_host[4]; |
141 | __be32 rem_host[4]; |
142 | __be16 loc_port; |
143 | __be16 rem_port; |
144 | /* total 64 bytes */ |
145 | }; |
146 | |
147 | enum { |
148 | = 0xffffffff, |
149 | EF4_FILTER_RX_DMAQ_ID_DROP = 0xfff |
150 | }; |
151 | |
152 | static inline void ef4_filter_init_rx(struct ef4_filter_spec *spec, |
153 | enum ef4_filter_priority priority, |
154 | enum ef4_filter_flags flags, |
155 | unsigned rxq_id) |
156 | { |
157 | memset(spec, 0, sizeof(*spec)); |
158 | spec->priority = priority; |
159 | spec->flags = EF4_FILTER_FLAG_RX | flags; |
160 | spec->rss_context = EF4_FILTER_RSS_CONTEXT_DEFAULT; |
161 | spec->dmaq_id = rxq_id; |
162 | } |
163 | |
164 | static inline void ef4_filter_init_tx(struct ef4_filter_spec *spec, |
165 | unsigned txq_id) |
166 | { |
167 | memset(spec, 0, sizeof(*spec)); |
168 | spec->priority = EF4_FILTER_PRI_REQUIRED; |
169 | spec->flags = EF4_FILTER_FLAG_TX; |
170 | spec->dmaq_id = txq_id; |
171 | } |
172 | |
173 | /** |
174 | * ef4_filter_set_ipv4_local - specify IPv4 host, transport protocol and port |
175 | * @spec: Specification to initialise |
176 | * @proto: Transport layer protocol number |
177 | * @host: Local host address (network byte order) |
178 | * @port: Local port (network byte order) |
179 | */ |
180 | static inline int |
181 | ef4_filter_set_ipv4_local(struct ef4_filter_spec *spec, u8 proto, |
182 | __be32 host, __be16 port) |
183 | { |
184 | spec->match_flags |= |
185 | EF4_FILTER_MATCH_ETHER_TYPE | EF4_FILTER_MATCH_IP_PROTO | |
186 | EF4_FILTER_MATCH_LOC_HOST | EF4_FILTER_MATCH_LOC_PORT; |
187 | spec->ether_type = htons(ETH_P_IP); |
188 | spec->ip_proto = proto; |
189 | spec->loc_host[0] = host; |
190 | spec->loc_port = port; |
191 | return 0; |
192 | } |
193 | |
194 | /** |
195 | * ef4_filter_set_ipv4_full - specify IPv4 hosts, transport protocol and ports |
196 | * @spec: Specification to initialise |
197 | * @proto: Transport layer protocol number |
198 | * @lhost: Local host address (network byte order) |
199 | * @lport: Local port (network byte order) |
200 | * @rhost: Remote host address (network byte order) |
201 | * @rport: Remote port (network byte order) |
202 | */ |
203 | static inline int |
204 | ef4_filter_set_ipv4_full(struct ef4_filter_spec *spec, u8 proto, |
205 | __be32 lhost, __be16 lport, |
206 | __be32 rhost, __be16 rport) |
207 | { |
208 | spec->match_flags |= |
209 | EF4_FILTER_MATCH_ETHER_TYPE | EF4_FILTER_MATCH_IP_PROTO | |
210 | EF4_FILTER_MATCH_LOC_HOST | EF4_FILTER_MATCH_LOC_PORT | |
211 | EF4_FILTER_MATCH_REM_HOST | EF4_FILTER_MATCH_REM_PORT; |
212 | spec->ether_type = htons(ETH_P_IP); |
213 | spec->ip_proto = proto; |
214 | spec->loc_host[0] = lhost; |
215 | spec->loc_port = lport; |
216 | spec->rem_host[0] = rhost; |
217 | spec->rem_port = rport; |
218 | return 0; |
219 | } |
220 | |
221 | enum { |
222 | EF4_FILTER_VID_UNSPEC = 0xffff, |
223 | }; |
224 | |
225 | /** |
226 | * ef4_filter_set_eth_local - specify local Ethernet address and/or VID |
227 | * @spec: Specification to initialise |
228 | * @vid: Outer VLAN ID to match, or %EF4_FILTER_VID_UNSPEC |
229 | * @addr: Local Ethernet MAC address, or %NULL |
230 | */ |
231 | static inline int ef4_filter_set_eth_local(struct ef4_filter_spec *spec, |
232 | u16 vid, const u8 *addr) |
233 | { |
234 | if (vid == EF4_FILTER_VID_UNSPEC && addr == NULL) |
235 | return -EINVAL; |
236 | |
237 | if (vid != EF4_FILTER_VID_UNSPEC) { |
238 | spec->match_flags |= EF4_FILTER_MATCH_OUTER_VID; |
239 | spec->outer_vid = htons(vid); |
240 | } |
241 | if (addr != NULL) { |
242 | spec->match_flags |= EF4_FILTER_MATCH_LOC_MAC; |
243 | ether_addr_copy(dst: spec->loc_mac, src: addr); |
244 | } |
245 | return 0; |
246 | } |
247 | |
248 | /** |
249 | * ef4_filter_set_uc_def - specify matching otherwise-unmatched unicast |
250 | * @spec: Specification to initialise |
251 | */ |
252 | static inline int ef4_filter_set_uc_def(struct ef4_filter_spec *spec) |
253 | { |
254 | spec->match_flags |= EF4_FILTER_MATCH_LOC_MAC_IG; |
255 | return 0; |
256 | } |
257 | |
258 | /** |
259 | * ef4_filter_set_mc_def - specify matching otherwise-unmatched multicast |
260 | * @spec: Specification to initialise |
261 | */ |
262 | static inline int ef4_filter_set_mc_def(struct ef4_filter_spec *spec) |
263 | { |
264 | spec->match_flags |= EF4_FILTER_MATCH_LOC_MAC_IG; |
265 | spec->loc_mac[0] = 1; |
266 | return 0; |
267 | } |
268 | |
269 | #endif /* EF4_FILTER_H */ |
270 | |