Merge tag 'timers-urgent-2020-08-14' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / drivers / net / ethernet / sfc / mcdi_filters.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /****************************************************************************
3  * Driver for Solarflare network controllers and boards
4  * Copyright 2005-2018 Solarflare Communications Inc.
5  * Copyright 2019-2020 Xilinx Inc.
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License version 2 as published
9  * by the Free Software Foundation, incorporated herein by reference.
10  */
11
12 #include "mcdi_filters.h"
13 #include "mcdi.h"
14 #include "nic.h"
15 #include "rx_common.h"
16
17 /* The maximum size of a shared RSS context */
18 /* TODO: this should really be from the mcdi protocol export */
19 #define EFX_EF10_MAX_SHARED_RSS_CONTEXT_SIZE 64UL
20
21 #define EFX_EF10_FILTER_ID_INVALID 0xffff
22
23 /* An arbitrary search limit for the software hash table */
24 #define EFX_EF10_FILTER_SEARCH_LIMIT 200
25
26 static struct efx_filter_spec *
27 efx_mcdi_filter_entry_spec(const struct efx_mcdi_filter_table *table,
28                            unsigned int filter_idx)
29 {
30         return (struct efx_filter_spec *)(table->entry[filter_idx].spec &
31                                           ~EFX_EF10_FILTER_FLAGS);
32 }
33
34 static unsigned int
35 efx_mcdi_filter_entry_flags(const struct efx_mcdi_filter_table *table,
36                            unsigned int filter_idx)
37 {
38         return table->entry[filter_idx].spec & EFX_EF10_FILTER_FLAGS;
39 }
40
41 static u32 efx_mcdi_filter_get_unsafe_id(u32 filter_id)
42 {
43         WARN_ON_ONCE(filter_id == EFX_EF10_FILTER_ID_INVALID);
44         return filter_id & (EFX_MCDI_FILTER_TBL_ROWS - 1);
45 }
46
47 static unsigned int efx_mcdi_filter_get_unsafe_pri(u32 filter_id)
48 {
49         return filter_id / (EFX_MCDI_FILTER_TBL_ROWS * 2);
50 }
51
52 static u32 efx_mcdi_filter_make_filter_id(unsigned int pri, u16 idx)
53 {
54         return pri * EFX_MCDI_FILTER_TBL_ROWS * 2 + idx;
55 }
56
57 /*
58  * Decide whether a filter should be exclusive or else should allow
59  * delivery to additional recipients.  Currently we decide that
60  * filters for specific local unicast MAC and IP addresses are
61  * exclusive.
62  */
63 static bool efx_mcdi_filter_is_exclusive(const struct efx_filter_spec *spec)
64 {
65         if (spec->match_flags & EFX_FILTER_MATCH_LOC_MAC &&
66             !is_multicast_ether_addr(spec->loc_mac))
67                 return true;
68
69         if ((spec->match_flags &
70              (EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_LOC_HOST)) ==
71             (EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_LOC_HOST)) {
72                 if (spec->ether_type == htons(ETH_P_IP) &&
73                     !ipv4_is_multicast(spec->loc_host[0]))
74                         return true;
75                 if (spec->ether_type == htons(ETH_P_IPV6) &&
76                     ((const u8 *)spec->loc_host)[0] != 0xff)
77                         return true;
78         }
79
80         return false;
81 }
82
83 static void
84 efx_mcdi_filter_set_entry(struct efx_mcdi_filter_table *table,
85                           unsigned int filter_idx,
86                           const struct efx_filter_spec *spec,
87                           unsigned int flags)
88 {
89         table->entry[filter_idx].spec = (unsigned long)spec | flags;
90 }
91
92 static void
93 efx_mcdi_filter_push_prep_set_match_fields(struct efx_nic *efx,
94                                            const struct efx_filter_spec *spec,
95                                            efx_dword_t *inbuf)
96 {
97         enum efx_encap_type encap_type = efx_filter_get_encap_type(spec);
98         u32 match_fields = 0, uc_match, mc_match;
99
100         MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP,
101                        efx_mcdi_filter_is_exclusive(spec) ?
102                        MC_CMD_FILTER_OP_IN_OP_INSERT :
103                        MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE);
104
105         /*
106          * Convert match flags and values.  Unlike almost
107          * everything else in MCDI, these fields are in
108          * network byte order.
109          */
110 #define COPY_VALUE(value, mcdi_field)                                        \
111         do {                                                         \
112                 match_fields |=                                      \
113                         1 << MC_CMD_FILTER_OP_IN_MATCH_ ##           \
114                         mcdi_field ## _LBN;                          \
115                 BUILD_BUG_ON(                                        \
116                         MC_CMD_FILTER_OP_IN_ ## mcdi_field ## _LEN < \
117                         sizeof(value));                              \
118                 memcpy(MCDI_PTR(inbuf, FILTER_OP_IN_ ## mcdi_field), \
119                        &value, sizeof(value));                       \
120         } while (0)
121 #define COPY_FIELD(gen_flag, gen_field, mcdi_field)                          \
122         if (spec->match_flags & EFX_FILTER_MATCH_ ## gen_flag) {     \
123                 COPY_VALUE(spec->gen_field, mcdi_field);             \
124         }
125         /*
126          * Handle encap filters first.  They will always be mismatch
127          * (unknown UC or MC) filters
128          */
129         if (encap_type) {
130                 /*
131                  * ether_type and outer_ip_proto need to be variables
132                  * because COPY_VALUE wants to memcpy them
133                  */
134                 __be16 ether_type =
135                         htons(encap_type & EFX_ENCAP_FLAG_IPV6 ?
136                               ETH_P_IPV6 : ETH_P_IP);
137                 u8 vni_type = MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_GENEVE;
138                 u8 outer_ip_proto;
139
140                 switch (encap_type & EFX_ENCAP_TYPES_MASK) {
141                 case EFX_ENCAP_TYPE_VXLAN:
142                         vni_type = MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_VXLAN;
143                         /* fallthrough */
144                 case EFX_ENCAP_TYPE_GENEVE:
145                         COPY_VALUE(ether_type, ETHER_TYPE);
146                         outer_ip_proto = IPPROTO_UDP;
147                         COPY_VALUE(outer_ip_proto, IP_PROTO);
148                         /*
149                          * We always need to set the type field, even
150                          * though we're not matching on the TNI.
151                          */
152                         MCDI_POPULATE_DWORD_1(inbuf,
153                                 FILTER_OP_EXT_IN_VNI_OR_VSID,
154                                 FILTER_OP_EXT_IN_VNI_TYPE,
155                                 vni_type);
156                         break;
157                 case EFX_ENCAP_TYPE_NVGRE:
158                         COPY_VALUE(ether_type, ETHER_TYPE);
159                         outer_ip_proto = IPPROTO_GRE;
160                         COPY_VALUE(outer_ip_proto, IP_PROTO);
161                         break;
162                 default:
163                         WARN_ON(1);
164                 }
165
166                 uc_match = MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_UCAST_DST_LBN;
167                 mc_match = MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_MCAST_DST_LBN;
168         } else {
169                 uc_match = MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_UCAST_DST_LBN;
170                 mc_match = MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_MCAST_DST_LBN;
171         }
172
173         if (spec->match_flags & EFX_FILTER_MATCH_LOC_MAC_IG)
174                 match_fields |=
175                         is_multicast_ether_addr(spec->loc_mac) ?
176                         1 << mc_match :
177                         1 << uc_match;
178         COPY_FIELD(REM_HOST, rem_host, SRC_IP);
179         COPY_FIELD(LOC_HOST, loc_host, DST_IP);
180         COPY_FIELD(REM_MAC, rem_mac, SRC_MAC);
181         COPY_FIELD(REM_PORT, rem_port, SRC_PORT);
182         COPY_FIELD(LOC_MAC, loc_mac, DST_MAC);
183         COPY_FIELD(LOC_PORT, loc_port, DST_PORT);
184         COPY_FIELD(ETHER_TYPE, ether_type, ETHER_TYPE);
185         COPY_FIELD(INNER_VID, inner_vid, INNER_VLAN);
186         COPY_FIELD(OUTER_VID, outer_vid, OUTER_VLAN);
187         COPY_FIELD(IP_PROTO, ip_proto, IP_PROTO);
188 #undef COPY_FIELD
189 #undef COPY_VALUE
190         MCDI_SET_DWORD(inbuf, FILTER_OP_IN_MATCH_FIELDS,
191                        match_fields);
192 }
193
194 static void efx_mcdi_filter_push_prep(struct efx_nic *efx,
195                                       const struct efx_filter_spec *spec,
196                                       efx_dword_t *inbuf, u64 handle,
197                                       struct efx_rss_context *ctx,
198                                       bool replacing)
199 {
200         u32 flags = spec->flags;
201
202         memset(inbuf, 0, MC_CMD_FILTER_OP_EXT_IN_LEN);
203
204         /* If RSS filter, caller better have given us an RSS context */
205         if (flags & EFX_FILTER_FLAG_RX_RSS) {
206                 /*
207                  * We don't have the ability to return an error, so we'll just
208                  * log a warning and disable RSS for the filter.
209                  */
210                 if (WARN_ON_ONCE(!ctx))
211                         flags &= ~EFX_FILTER_FLAG_RX_RSS;
212                 else if (WARN_ON_ONCE(ctx->context_id == EFX_MCDI_RSS_CONTEXT_INVALID))
213                         flags &= ~EFX_FILTER_FLAG_RX_RSS;
214         }
215
216         if (replacing) {
217                 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP,
218                                MC_CMD_FILTER_OP_IN_OP_REPLACE);
219                 MCDI_SET_QWORD(inbuf, FILTER_OP_IN_HANDLE, handle);
220         } else {
221                 efx_mcdi_filter_push_prep_set_match_fields(efx, spec, inbuf);
222         }
223
224         MCDI_SET_DWORD(inbuf, FILTER_OP_IN_PORT_ID, efx->vport_id);
225         MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_DEST,
226                        spec->dmaq_id == EFX_FILTER_RX_DMAQ_ID_DROP ?
227                        MC_CMD_FILTER_OP_IN_RX_DEST_DROP :
228                        MC_CMD_FILTER_OP_IN_RX_DEST_HOST);
229         MCDI_SET_DWORD(inbuf, FILTER_OP_IN_TX_DOMAIN, 0);
230         MCDI_SET_DWORD(inbuf, FILTER_OP_IN_TX_DEST,
231                        MC_CMD_FILTER_OP_IN_TX_DEST_DEFAULT);
232         MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_QUEUE,
233                        spec->dmaq_id == EFX_FILTER_RX_DMAQ_ID_DROP ?
234                        0 : spec->dmaq_id);
235         MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_MODE,
236                        (flags & EFX_FILTER_FLAG_RX_RSS) ?
237                        MC_CMD_FILTER_OP_IN_RX_MODE_RSS :
238                        MC_CMD_FILTER_OP_IN_RX_MODE_SIMPLE);
239         if (flags & EFX_FILTER_FLAG_RX_RSS)
240                 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_RX_CONTEXT, ctx->context_id);
241 }
242
243 static int efx_mcdi_filter_push(struct efx_nic *efx,
244                                 const struct efx_filter_spec *spec, u64 *handle,
245                                 struct efx_rss_context *ctx, bool replacing)
246 {
247         MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN);
248         MCDI_DECLARE_BUF(outbuf, MC_CMD_FILTER_OP_EXT_OUT_LEN);
249         size_t outlen;
250         int rc;
251
252         efx_mcdi_filter_push_prep(efx, spec, inbuf, *handle, ctx, replacing);
253         rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FILTER_OP, inbuf, sizeof(inbuf),
254                                 outbuf, sizeof(outbuf), &outlen);
255         if (rc && spec->priority != EFX_FILTER_PRI_HINT)
256                 efx_mcdi_display_error(efx, MC_CMD_FILTER_OP, sizeof(inbuf),
257                                        outbuf, outlen, rc);
258         if (rc == 0)
259                 *handle = MCDI_QWORD(outbuf, FILTER_OP_OUT_HANDLE);
260         if (rc == -ENOSPC)
261                 rc = -EBUSY; /* to match efx_farch_filter_insert() */
262         return rc;
263 }
264
265 static u32 efx_mcdi_filter_mcdi_flags_from_spec(const struct efx_filter_spec *spec)
266 {
267         enum efx_encap_type encap_type = efx_filter_get_encap_type(spec);
268         unsigned int match_flags = spec->match_flags;
269         unsigned int uc_match, mc_match;
270         u32 mcdi_flags = 0;
271
272 #define MAP_FILTER_TO_MCDI_FLAG(gen_flag, mcdi_field, encap) {          \
273                 unsigned int  old_match_flags = match_flags;            \
274                 match_flags &= ~EFX_FILTER_MATCH_ ## gen_flag;          \
275                 if (match_flags != old_match_flags)                     \
276                         mcdi_flags |=                                   \
277                                 (1 << ((encap) ?                        \
278                                        MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_ ## \
279                                        mcdi_field ## _LBN :             \
280                                        MC_CMD_FILTER_OP_EXT_IN_MATCH_ ##\
281                                        mcdi_field ## _LBN));            \
282         }
283         /* inner or outer based on encap type */
284         MAP_FILTER_TO_MCDI_FLAG(REM_HOST, SRC_IP, encap_type);
285         MAP_FILTER_TO_MCDI_FLAG(LOC_HOST, DST_IP, encap_type);
286         MAP_FILTER_TO_MCDI_FLAG(REM_MAC, SRC_MAC, encap_type);
287         MAP_FILTER_TO_MCDI_FLAG(REM_PORT, SRC_PORT, encap_type);
288         MAP_FILTER_TO_MCDI_FLAG(LOC_MAC, DST_MAC, encap_type);
289         MAP_FILTER_TO_MCDI_FLAG(LOC_PORT, DST_PORT, encap_type);
290         MAP_FILTER_TO_MCDI_FLAG(ETHER_TYPE, ETHER_TYPE, encap_type);
291         MAP_FILTER_TO_MCDI_FLAG(IP_PROTO, IP_PROTO, encap_type);
292         /* always outer */
293         MAP_FILTER_TO_MCDI_FLAG(INNER_VID, INNER_VLAN, false);
294         MAP_FILTER_TO_MCDI_FLAG(OUTER_VID, OUTER_VLAN, false);
295 #undef MAP_FILTER_TO_MCDI_FLAG
296
297         /* special handling for encap type, and mismatch */
298         if (encap_type) {
299                 match_flags &= ~EFX_FILTER_MATCH_ENCAP_TYPE;
300                 mcdi_flags |=
301                         (1 << MC_CMD_FILTER_OP_EXT_IN_MATCH_ETHER_TYPE_LBN);
302                 mcdi_flags |= (1 << MC_CMD_FILTER_OP_EXT_IN_MATCH_IP_PROTO_LBN);
303
304                 uc_match = MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_UCAST_DST_LBN;
305                 mc_match = MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_MCAST_DST_LBN;
306         } else {
307                 uc_match = MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_UCAST_DST_LBN;
308                 mc_match = MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_MCAST_DST_LBN;
309         }
310
311         if (match_flags & EFX_FILTER_MATCH_LOC_MAC_IG) {
312                 match_flags &= ~EFX_FILTER_MATCH_LOC_MAC_IG;
313                 mcdi_flags |=
314                         is_multicast_ether_addr(spec->loc_mac) ?
315                         1 << mc_match :
316                         1 << uc_match;
317         }
318
319         /* Did we map them all? */
320         WARN_ON_ONCE(match_flags);
321
322         return mcdi_flags;
323 }
324
325 static int efx_mcdi_filter_pri(struct efx_mcdi_filter_table *table,
326                                const struct efx_filter_spec *spec)
327 {
328         u32 mcdi_flags = efx_mcdi_filter_mcdi_flags_from_spec(spec);
329         unsigned int match_pri;
330
331         for (match_pri = 0;
332              match_pri < table->rx_match_count;
333              match_pri++)
334                 if (table->rx_match_mcdi_flags[match_pri] == mcdi_flags)
335                         return match_pri;
336
337         return -EPROTONOSUPPORT;
338 }
339
340 static s32 efx_mcdi_filter_insert_locked(struct efx_nic *efx,
341                                          struct efx_filter_spec *spec,
342                                          bool replace_equal)
343 {
344         DECLARE_BITMAP(mc_rem_map, EFX_EF10_FILTER_SEARCH_LIMIT);
345         struct efx_mcdi_filter_table *table;
346         struct efx_filter_spec *saved_spec;
347         struct efx_rss_context *ctx = NULL;
348         unsigned int match_pri, hash;
349         unsigned int priv_flags;
350         bool rss_locked = false;
351         bool replacing = false;
352         unsigned int depth, i;
353         int ins_index = -1;
354         DEFINE_WAIT(wait);
355         bool is_mc_recip;
356         s32 rc;
357
358         WARN_ON(!rwsem_is_locked(&efx->filter_sem));
359         table = efx->filter_state;
360         down_write(&table->lock);
361
362         /* For now, only support RX filters */
363         if ((spec->flags & (EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX)) !=
364             EFX_FILTER_FLAG_RX) {
365                 rc = -EINVAL;
366                 goto out_unlock;
367         }
368
369         rc = efx_mcdi_filter_pri(table, spec);
370         if (rc < 0)
371                 goto out_unlock;
372         match_pri = rc;
373
374         hash = efx_filter_spec_hash(spec);
375         is_mc_recip = efx_filter_is_mc_recipient(spec);
376         if (is_mc_recip)
377                 bitmap_zero(mc_rem_map, EFX_EF10_FILTER_SEARCH_LIMIT);
378
379         if (spec->flags & EFX_FILTER_FLAG_RX_RSS) {
380                 mutex_lock(&efx->rss_lock);
381                 rss_locked = true;
382                 if (spec->rss_context)
383                         ctx = efx_find_rss_context_entry(efx, spec->rss_context);
384                 else
385                         ctx = &efx->rss_context;
386                 if (!ctx) {
387                         rc = -ENOENT;
388                         goto out_unlock;
389                 }
390                 if (ctx->context_id == EFX_MCDI_RSS_CONTEXT_INVALID) {
391                         rc = -EOPNOTSUPP;
392                         goto out_unlock;
393                 }
394         }
395
396         /* Find any existing filters with the same match tuple or
397          * else a free slot to insert at.
398          */
399         for (depth = 1; depth < EFX_EF10_FILTER_SEARCH_LIMIT; depth++) {
400                 i = (hash + depth) & (EFX_MCDI_FILTER_TBL_ROWS - 1);
401                 saved_spec = efx_mcdi_filter_entry_spec(table, i);
402
403                 if (!saved_spec) {
404                         if (ins_index < 0)
405                                 ins_index = i;
406                 } else if (efx_filter_spec_equal(spec, saved_spec)) {
407                         if (spec->priority < saved_spec->priority &&
408                             spec->priority != EFX_FILTER_PRI_AUTO) {
409                                 rc = -EPERM;
410                                 goto out_unlock;
411                         }
412                         if (!is_mc_recip) {
413                                 /* This is the only one */
414                                 if (spec->priority ==
415                                     saved_spec->priority &&
416                                     !replace_equal) {
417                                         rc = -EEXIST;
418                                         goto out_unlock;
419                                 }
420                                 ins_index = i;
421                                 break;
422                         } else if (spec->priority >
423                                    saved_spec->priority ||
424                                    (spec->priority ==
425                                     saved_spec->priority &&
426                                     replace_equal)) {
427                                 if (ins_index < 0)
428                                         ins_index = i;
429                                 else
430                                         __set_bit(depth, mc_rem_map);
431                         }
432                 }
433         }
434
435         /* Once we reach the maximum search depth, use the first suitable
436          * slot, or return -EBUSY if there was none
437          */
438         if (ins_index < 0) {
439                 rc = -EBUSY;
440                 goto out_unlock;
441         }
442
443         /* Create a software table entry if necessary. */
444         saved_spec = efx_mcdi_filter_entry_spec(table, ins_index);
445         if (saved_spec) {
446                 if (spec->priority == EFX_FILTER_PRI_AUTO &&
447                     saved_spec->priority >= EFX_FILTER_PRI_AUTO) {
448                         /* Just make sure it won't be removed */
449                         if (saved_spec->priority > EFX_FILTER_PRI_AUTO)
450                                 saved_spec->flags |= EFX_FILTER_FLAG_RX_OVER_AUTO;
451                         table->entry[ins_index].spec &=
452                                 ~EFX_EF10_FILTER_FLAG_AUTO_OLD;
453                         rc = ins_index;
454                         goto out_unlock;
455                 }
456                 replacing = true;
457                 priv_flags = efx_mcdi_filter_entry_flags(table, ins_index);
458         } else {
459                 saved_spec = kmalloc(sizeof(*spec), GFP_ATOMIC);
460                 if (!saved_spec) {
461                         rc = -ENOMEM;
462                         goto out_unlock;
463                 }
464                 *saved_spec = *spec;
465                 priv_flags = 0;
466         }
467         efx_mcdi_filter_set_entry(table, ins_index, saved_spec, priv_flags);
468
469         /* Actually insert the filter on the HW */
470         rc = efx_mcdi_filter_push(efx, spec, &table->entry[ins_index].handle,
471                                   ctx, replacing);
472
473         if (rc == -EINVAL && efx->must_realloc_vis)
474                 /* The MC rebooted under us, causing it to reject our filter
475                  * insertion as pointing to an invalid VI (spec->dmaq_id).
476                  */
477                 rc = -EAGAIN;
478
479         /* Finalise the software table entry */
480         if (rc == 0) {
481                 if (replacing) {
482                         /* Update the fields that may differ */
483                         if (saved_spec->priority == EFX_FILTER_PRI_AUTO)
484                                 saved_spec->flags |=
485                                         EFX_FILTER_FLAG_RX_OVER_AUTO;
486                         saved_spec->priority = spec->priority;
487                         saved_spec->flags &= EFX_FILTER_FLAG_RX_OVER_AUTO;
488                         saved_spec->flags |= spec->flags;
489                         saved_spec->rss_context = spec->rss_context;
490                         saved_spec->dmaq_id = spec->dmaq_id;
491                 }
492         } else if (!replacing) {
493                 kfree(saved_spec);
494                 saved_spec = NULL;
495         } else {
496                 /* We failed to replace, so the old filter is still present.
497                  * Roll back the software table to reflect this.  In fact the
498                  * efx_mcdi_filter_set_entry() call below will do the right
499                  * thing, so nothing extra is needed here.
500                  */
501         }
502         efx_mcdi_filter_set_entry(table, ins_index, saved_spec, priv_flags);
503
504         /* Remove and finalise entries for lower-priority multicast
505          * recipients
506          */
507         if (is_mc_recip) {
508                 MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN);
509                 unsigned int depth, i;
510
511                 memset(inbuf, 0, sizeof(inbuf));
512
513                 for (depth = 0; depth < EFX_EF10_FILTER_SEARCH_LIMIT; depth++) {
514                         if (!test_bit(depth, mc_rem_map))
515                                 continue;
516
517                         i = (hash + depth) & (EFX_MCDI_FILTER_TBL_ROWS - 1);
518                         saved_spec = efx_mcdi_filter_entry_spec(table, i);
519                         priv_flags = efx_mcdi_filter_entry_flags(table, i);
520
521                         if (rc == 0) {
522                                 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP,
523                                                MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE);
524                                 MCDI_SET_QWORD(inbuf, FILTER_OP_IN_HANDLE,
525                                                table->entry[i].handle);
526                                 rc = efx_mcdi_rpc(efx, MC_CMD_FILTER_OP,
527                                                   inbuf, sizeof(inbuf),
528                                                   NULL, 0, NULL);
529                         }
530
531                         if (rc == 0) {
532                                 kfree(saved_spec);
533                                 saved_spec = NULL;
534                                 priv_flags = 0;
535                         }
536                         efx_mcdi_filter_set_entry(table, i, saved_spec,
537                                                   priv_flags);
538                 }
539         }
540
541         /* If successful, return the inserted filter ID */
542         if (rc == 0)
543                 rc = efx_mcdi_filter_make_filter_id(match_pri, ins_index);
544
545 out_unlock:
546         if (rss_locked)
547                 mutex_unlock(&efx->rss_lock);
548         up_write(&table->lock);
549         return rc;
550 }
551
552 s32 efx_mcdi_filter_insert(struct efx_nic *efx, struct efx_filter_spec *spec,
553                            bool replace_equal)
554 {
555         s32 ret;
556
557         down_read(&efx->filter_sem);
558         ret = efx_mcdi_filter_insert_locked(efx, spec, replace_equal);
559         up_read(&efx->filter_sem);
560
561         return ret;
562 }
563
564 /*
565  * Remove a filter.
566  * If !by_index, remove by ID
567  * If by_index, remove by index
568  * Filter ID may come from userland and must be range-checked.
569  * Caller must hold efx->filter_sem for read, and efx->filter_state->lock
570  * for write.
571  */
572 static int efx_mcdi_filter_remove_internal(struct efx_nic *efx,
573                                            unsigned int priority_mask,
574                                            u32 filter_id, bool by_index)
575 {
576         unsigned int filter_idx = efx_mcdi_filter_get_unsafe_id(filter_id);
577         struct efx_mcdi_filter_table *table = efx->filter_state;
578         MCDI_DECLARE_BUF(inbuf,
579                          MC_CMD_FILTER_OP_IN_HANDLE_OFST +
580                          MC_CMD_FILTER_OP_IN_HANDLE_LEN);
581         struct efx_filter_spec *spec;
582         DEFINE_WAIT(wait);
583         int rc;
584
585         spec = efx_mcdi_filter_entry_spec(table, filter_idx);
586         if (!spec ||
587             (!by_index &&
588              efx_mcdi_filter_pri(table, spec) !=
589              efx_mcdi_filter_get_unsafe_pri(filter_id)))
590                 return -ENOENT;
591
592         if (spec->flags & EFX_FILTER_FLAG_RX_OVER_AUTO &&
593             priority_mask == (1U << EFX_FILTER_PRI_AUTO)) {
594                 /* Just remove flags */
595                 spec->flags &= ~EFX_FILTER_FLAG_RX_OVER_AUTO;
596                 table->entry[filter_idx].spec &= ~EFX_EF10_FILTER_FLAG_AUTO_OLD;
597                 return 0;
598         }
599
600         if (!(priority_mask & (1U << spec->priority)))
601                 return -ENOENT;
602
603         if (spec->flags & EFX_FILTER_FLAG_RX_OVER_AUTO) {
604                 /* Reset to an automatic filter */
605
606                 struct efx_filter_spec new_spec = *spec;
607
608                 new_spec.priority = EFX_FILTER_PRI_AUTO;
609                 new_spec.flags = (EFX_FILTER_FLAG_RX |
610                                   (efx_rss_active(&efx->rss_context) ?
611                                    EFX_FILTER_FLAG_RX_RSS : 0));
612                 new_spec.dmaq_id = 0;
613                 new_spec.rss_context = 0;
614                 rc = efx_mcdi_filter_push(efx, &new_spec,
615                                           &table->entry[filter_idx].handle,
616                                           &efx->rss_context,
617                                           true);
618
619                 if (rc == 0)
620                         *spec = new_spec;
621         } else {
622                 /* Really remove the filter */
623
624                 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP,
625                                efx_mcdi_filter_is_exclusive(spec) ?
626                                MC_CMD_FILTER_OP_IN_OP_REMOVE :
627                                MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE);
628                 MCDI_SET_QWORD(inbuf, FILTER_OP_IN_HANDLE,
629                                table->entry[filter_idx].handle);
630                 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FILTER_OP,
631                                         inbuf, sizeof(inbuf), NULL, 0, NULL);
632
633                 if ((rc == 0) || (rc == -ENOENT)) {
634                         /* Filter removed OK or didn't actually exist */
635                         kfree(spec);
636                         efx_mcdi_filter_set_entry(table, filter_idx, NULL, 0);
637                 } else {
638                         efx_mcdi_display_error(efx, MC_CMD_FILTER_OP,
639                                                MC_CMD_FILTER_OP_EXT_IN_LEN,
640                                                NULL, 0, rc);
641                 }
642         }
643
644         return rc;
645 }
646
647 /* Remove filters that weren't renewed. */
648 static void efx_mcdi_filter_remove_old(struct efx_nic *efx)
649 {
650         struct efx_mcdi_filter_table *table = efx->filter_state;
651         int remove_failed = 0;
652         int remove_noent = 0;
653         int rc;
654         int i;
655
656         down_write(&table->lock);
657         for (i = 0; i < EFX_MCDI_FILTER_TBL_ROWS; i++) {
658                 if (READ_ONCE(table->entry[i].spec) &
659                     EFX_EF10_FILTER_FLAG_AUTO_OLD) {
660                         rc = efx_mcdi_filter_remove_internal(efx,
661                                         1U << EFX_FILTER_PRI_AUTO, i, true);
662                         if (rc == -ENOENT)
663                                 remove_noent++;
664                         else if (rc)
665                                 remove_failed++;
666                 }
667         }
668         up_write(&table->lock);
669
670         if (remove_failed)
671                 netif_info(efx, drv, efx->net_dev,
672                            "%s: failed to remove %d filters\n",
673                            __func__, remove_failed);
674         if (remove_noent)
675                 netif_info(efx, drv, efx->net_dev,
676                            "%s: failed to remove %d non-existent filters\n",
677                            __func__, remove_noent);
678 }
679
680 int efx_mcdi_filter_remove_safe(struct efx_nic *efx,
681                                 enum efx_filter_priority priority,
682                                 u32 filter_id)
683 {
684         struct efx_mcdi_filter_table *table;
685         int rc;
686
687         down_read(&efx->filter_sem);
688         table = efx->filter_state;
689         down_write(&table->lock);
690         rc = efx_mcdi_filter_remove_internal(efx, 1U << priority, filter_id,
691                                              false);
692         up_write(&table->lock);
693         up_read(&efx->filter_sem);
694         return rc;
695 }
696
697 /* Caller must hold efx->filter_sem for read */
698 static void efx_mcdi_filter_remove_unsafe(struct efx_nic *efx,
699                                           enum efx_filter_priority priority,
700                                           u32 filter_id)
701 {
702         struct efx_mcdi_filter_table *table = efx->filter_state;
703
704         if (filter_id == EFX_EF10_FILTER_ID_INVALID)
705                 return;
706
707         down_write(&table->lock);
708         efx_mcdi_filter_remove_internal(efx, 1U << priority, filter_id,
709                                         true);
710         up_write(&table->lock);
711 }
712
713 int efx_mcdi_filter_get_safe(struct efx_nic *efx,
714                              enum efx_filter_priority priority,
715                              u32 filter_id, struct efx_filter_spec *spec)
716 {
717         unsigned int filter_idx = efx_mcdi_filter_get_unsafe_id(filter_id);
718         const struct efx_filter_spec *saved_spec;
719         struct efx_mcdi_filter_table *table;
720         int rc;
721
722         down_read(&efx->filter_sem);
723         table = efx->filter_state;
724         down_read(&table->lock);
725         saved_spec = efx_mcdi_filter_entry_spec(table, filter_idx);
726         if (saved_spec && saved_spec->priority == priority &&
727             efx_mcdi_filter_pri(table, saved_spec) ==
728             efx_mcdi_filter_get_unsafe_pri(filter_id)) {
729                 *spec = *saved_spec;
730                 rc = 0;
731         } else {
732                 rc = -ENOENT;
733         }
734         up_read(&table->lock);
735         up_read(&efx->filter_sem);
736         return rc;
737 }
738
739 static int efx_mcdi_filter_insert_addr_list(struct efx_nic *efx,
740                                             struct efx_mcdi_filter_vlan *vlan,
741                                             bool multicast, bool rollback)
742 {
743         struct efx_mcdi_filter_table *table = efx->filter_state;
744         struct efx_mcdi_dev_addr *addr_list;
745         enum efx_filter_flags filter_flags;
746         struct efx_filter_spec spec;
747         u8 baddr[ETH_ALEN];
748         unsigned int i, j;
749         int addr_count;
750         u16 *ids;
751         int rc;
752
753         if (multicast) {
754                 addr_list = table->dev_mc_list;
755                 addr_count = table->dev_mc_count;
756                 ids = vlan->mc;
757         } else {
758                 addr_list = table->dev_uc_list;
759                 addr_count = table->dev_uc_count;
760                 ids = vlan->uc;
761         }
762
763         filter_flags = efx_rss_active(&efx->rss_context) ? EFX_FILTER_FLAG_RX_RSS : 0;
764
765         /* Insert/renew filters */
766         for (i = 0; i < addr_count; i++) {
767                 EFX_WARN_ON_PARANOID(ids[i] != EFX_EF10_FILTER_ID_INVALID);
768                 efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO, filter_flags, 0);
769                 efx_filter_set_eth_local(&spec, vlan->vid, addr_list[i].addr);
770                 rc = efx_mcdi_filter_insert_locked(efx, &spec, true);
771                 if (rc < 0) {
772                         if (rollback) {
773                                 netif_info(efx, drv, efx->net_dev,
774                                            "efx_mcdi_filter_insert failed rc=%d\n",
775                                            rc);
776                                 /* Fall back to promiscuous */
777                                 for (j = 0; j < i; j++) {
778                                         efx_mcdi_filter_remove_unsafe(
779                                                 efx, EFX_FILTER_PRI_AUTO,
780                                                 ids[j]);
781                                         ids[j] = EFX_EF10_FILTER_ID_INVALID;
782                                 }
783                                 return rc;
784                         } else {
785                                 /* keep invalid ID, and carry on */
786                         }
787                 } else {
788                         ids[i] = efx_mcdi_filter_get_unsafe_id(rc);
789                 }
790         }
791
792         if (multicast && rollback) {
793                 /* Also need an Ethernet broadcast filter */
794                 EFX_WARN_ON_PARANOID(vlan->default_filters[EFX_EF10_BCAST] !=
795                                      EFX_EF10_FILTER_ID_INVALID);
796                 efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO, filter_flags, 0);
797                 eth_broadcast_addr(baddr);
798                 efx_filter_set_eth_local(&spec, vlan->vid, baddr);
799                 rc = efx_mcdi_filter_insert_locked(efx, &spec, true);
800                 if (rc < 0) {
801                         netif_warn(efx, drv, efx->net_dev,
802                                    "Broadcast filter insert failed rc=%d\n", rc);
803                         /* Fall back to promiscuous */
804                         for (j = 0; j < i; j++) {
805                                 efx_mcdi_filter_remove_unsafe(
806                                         efx, EFX_FILTER_PRI_AUTO,
807                                         ids[j]);
808                                 ids[j] = EFX_EF10_FILTER_ID_INVALID;
809                         }
810                         return rc;
811                 } else {
812                         vlan->default_filters[EFX_EF10_BCAST] =
813                                 efx_mcdi_filter_get_unsafe_id(rc);
814                 }
815         }
816
817         return 0;
818 }
819
820 static int efx_mcdi_filter_insert_def(struct efx_nic *efx,
821                                       struct efx_mcdi_filter_vlan *vlan,
822                                       enum efx_encap_type encap_type,
823                                       bool multicast, bool rollback)
824 {
825         struct efx_mcdi_filter_table *table = efx->filter_state;
826         enum efx_filter_flags filter_flags;
827         struct efx_filter_spec spec;
828         u8 baddr[ETH_ALEN];
829         int rc;
830         u16 *id;
831
832         filter_flags = efx_rss_active(&efx->rss_context) ? EFX_FILTER_FLAG_RX_RSS : 0;
833
834         efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO, filter_flags, 0);
835
836         if (multicast)
837                 efx_filter_set_mc_def(&spec);
838         else
839                 efx_filter_set_uc_def(&spec);
840
841         if (encap_type) {
842                 if (efx_has_cap(efx, VXLAN_NVGRE))
843                         efx_filter_set_encap_type(&spec, encap_type);
844                 else
845                         /*
846                          * don't insert encap filters on non-supporting
847                          * platforms. ID will be left as INVALID.
848                          */
849                         return 0;
850         }
851
852         if (vlan->vid != EFX_FILTER_VID_UNSPEC)
853                 efx_filter_set_eth_local(&spec, vlan->vid, NULL);
854
855         rc = efx_mcdi_filter_insert_locked(efx, &spec, true);
856         if (rc < 0) {
857                 const char *um = multicast ? "Multicast" : "Unicast";
858                 const char *encap_name = "";
859                 const char *encap_ipv = "";
860
861                 if ((encap_type & EFX_ENCAP_TYPES_MASK) ==
862                     EFX_ENCAP_TYPE_VXLAN)
863                         encap_name = "VXLAN ";
864                 else if ((encap_type & EFX_ENCAP_TYPES_MASK) ==
865                          EFX_ENCAP_TYPE_NVGRE)
866                         encap_name = "NVGRE ";
867                 else if ((encap_type & EFX_ENCAP_TYPES_MASK) ==
868                          EFX_ENCAP_TYPE_GENEVE)
869                         encap_name = "GENEVE ";
870                 if (encap_type & EFX_ENCAP_FLAG_IPV6)
871                         encap_ipv = "IPv6 ";
872                 else if (encap_type)
873                         encap_ipv = "IPv4 ";
874
875                 /*
876                  * unprivileged functions can't insert mismatch filters
877                  * for encapsulated or unicast traffic, so downgrade
878                  * those warnings to debug.
879                  */
880                 netif_cond_dbg(efx, drv, efx->net_dev,
881                                rc == -EPERM && (encap_type || !multicast), warn,
882                                "%s%s%s mismatch filter insert failed rc=%d\n",
883                                encap_name, encap_ipv, um, rc);
884         } else if (multicast) {
885                 /* mapping from encap types to default filter IDs (multicast) */
886                 static enum efx_mcdi_filter_default_filters map[] = {
887                         [EFX_ENCAP_TYPE_NONE] = EFX_EF10_MCDEF,
888                         [EFX_ENCAP_TYPE_VXLAN] = EFX_EF10_VXLAN4_MCDEF,
889                         [EFX_ENCAP_TYPE_NVGRE] = EFX_EF10_NVGRE4_MCDEF,
890                         [EFX_ENCAP_TYPE_GENEVE] = EFX_EF10_GENEVE4_MCDEF,
891                         [EFX_ENCAP_TYPE_VXLAN | EFX_ENCAP_FLAG_IPV6] =
892                                 EFX_EF10_VXLAN6_MCDEF,
893                         [EFX_ENCAP_TYPE_NVGRE | EFX_ENCAP_FLAG_IPV6] =
894                                 EFX_EF10_NVGRE6_MCDEF,
895                         [EFX_ENCAP_TYPE_GENEVE | EFX_ENCAP_FLAG_IPV6] =
896                                 EFX_EF10_GENEVE6_MCDEF,
897                 };
898
899                 /* quick bounds check (BCAST result impossible) */
900                 BUILD_BUG_ON(EFX_EF10_BCAST != 0);
901                 if (encap_type >= ARRAY_SIZE(map) || map[encap_type] == 0) {
902                         WARN_ON(1);
903                         return -EINVAL;
904                 }
905                 /* then follow map */
906                 id = &vlan->default_filters[map[encap_type]];
907
908                 EFX_WARN_ON_PARANOID(*id != EFX_EF10_FILTER_ID_INVALID);
909                 *id = efx_mcdi_filter_get_unsafe_id(rc);
910                 if (!table->mc_chaining && !encap_type) {
911                         /* Also need an Ethernet broadcast filter */
912                         efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO,
913                                            filter_flags, 0);
914                         eth_broadcast_addr(baddr);
915                         efx_filter_set_eth_local(&spec, vlan->vid, baddr);
916                         rc = efx_mcdi_filter_insert_locked(efx, &spec, true);
917                         if (rc < 0) {
918                                 netif_warn(efx, drv, efx->net_dev,
919                                            "Broadcast filter insert failed rc=%d\n",
920                                            rc);
921                                 if (rollback) {
922                                         /* Roll back the mc_def filter */
923                                         efx_mcdi_filter_remove_unsafe(
924                                                         efx, EFX_FILTER_PRI_AUTO,
925                                                         *id);
926                                         *id = EFX_EF10_FILTER_ID_INVALID;
927                                         return rc;
928                                 }
929                         } else {
930                                 EFX_WARN_ON_PARANOID(
931                                         vlan->default_filters[EFX_EF10_BCAST] !=
932                                         EFX_EF10_FILTER_ID_INVALID);
933                                 vlan->default_filters[EFX_EF10_BCAST] =
934                                         efx_mcdi_filter_get_unsafe_id(rc);
935                         }
936                 }
937                 rc = 0;
938         } else {
939                 /* mapping from encap types to default filter IDs (unicast) */
940                 static enum efx_mcdi_filter_default_filters map[] = {
941                         [EFX_ENCAP_TYPE_NONE] = EFX_EF10_UCDEF,
942                         [EFX_ENCAP_TYPE_VXLAN] = EFX_EF10_VXLAN4_UCDEF,
943                         [EFX_ENCAP_TYPE_NVGRE] = EFX_EF10_NVGRE4_UCDEF,
944                         [EFX_ENCAP_TYPE_GENEVE] = EFX_EF10_GENEVE4_UCDEF,
945                         [EFX_ENCAP_TYPE_VXLAN | EFX_ENCAP_FLAG_IPV6] =
946                                 EFX_EF10_VXLAN6_UCDEF,
947                         [EFX_ENCAP_TYPE_NVGRE | EFX_ENCAP_FLAG_IPV6] =
948                                 EFX_EF10_NVGRE6_UCDEF,
949                         [EFX_ENCAP_TYPE_GENEVE | EFX_ENCAP_FLAG_IPV6] =
950                                 EFX_EF10_GENEVE6_UCDEF,
951                 };
952
953                 /* quick bounds check (BCAST result impossible) */
954                 BUILD_BUG_ON(EFX_EF10_BCAST != 0);
955                 if (encap_type >= ARRAY_SIZE(map) || map[encap_type] == 0) {
956                         WARN_ON(1);
957                         return -EINVAL;
958                 }
959                 /* then follow map */
960                 id = &vlan->default_filters[map[encap_type]];
961                 EFX_WARN_ON_PARANOID(*id != EFX_EF10_FILTER_ID_INVALID);
962                 *id = rc;
963                 rc = 0;
964         }
965         return rc;
966 }
967
968 /*
969  * Caller must hold efx->filter_sem for read if race against
970  * efx_mcdi_filter_table_remove() is possible
971  */
972 static void efx_mcdi_filter_vlan_sync_rx_mode(struct efx_nic *efx,
973                                               struct efx_mcdi_filter_vlan *vlan)
974 {
975         struct efx_mcdi_filter_table *table = efx->filter_state;
976
977         /*
978          * Do not install unspecified VID if VLAN filtering is enabled.
979          * Do not install all specified VIDs if VLAN filtering is disabled.
980          */
981         if ((vlan->vid == EFX_FILTER_VID_UNSPEC) == table->vlan_filter)
982                 return;
983
984         /* Insert/renew unicast filters */
985         if (table->uc_promisc) {
986                 efx_mcdi_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_NONE,
987                                            false, false);
988                 efx_mcdi_filter_insert_addr_list(efx, vlan, false, false);
989         } else {
990                 /*
991                  * If any of the filters failed to insert, fall back to
992                  * promiscuous mode - add in the uc_def filter.  But keep
993                  * our individual unicast filters.
994                  */
995                 if (efx_mcdi_filter_insert_addr_list(efx, vlan, false, false))
996                         efx_mcdi_filter_insert_def(efx, vlan,
997                                                    EFX_ENCAP_TYPE_NONE,
998                                                    false, false);
999         }
1000         efx_mcdi_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_VXLAN,
1001                                    false, false);
1002         efx_mcdi_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_VXLAN |
1003                                               EFX_ENCAP_FLAG_IPV6,
1004                                    false, false);
1005         efx_mcdi_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_NVGRE,
1006                                    false, false);
1007         efx_mcdi_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_NVGRE |
1008                                               EFX_ENCAP_FLAG_IPV6,
1009                                    false, false);
1010         efx_mcdi_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_GENEVE,
1011                                    false, false);
1012         efx_mcdi_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_GENEVE |
1013                                               EFX_ENCAP_FLAG_IPV6,
1014                                    false, false);
1015
1016         /*
1017          * Insert/renew multicast filters
1018          *
1019          * If changing promiscuous state with cascaded multicast filters, remove
1020          * old filters first, so that packets are dropped rather than duplicated
1021          */
1022         if (table->mc_chaining && table->mc_promisc_last != table->mc_promisc)
1023                 efx_mcdi_filter_remove_old(efx);
1024         if (table->mc_promisc) {
1025                 if (table->mc_chaining) {
1026                         /*
1027                          * If we failed to insert promiscuous filters, rollback
1028                          * and fall back to individual multicast filters
1029                          */
1030                         if (efx_mcdi_filter_insert_def(efx, vlan,
1031                                                        EFX_ENCAP_TYPE_NONE,
1032                                                        true, true)) {
1033                                 /* Changing promisc state, so remove old filters */
1034                                 efx_mcdi_filter_remove_old(efx);
1035                                 efx_mcdi_filter_insert_addr_list(efx, vlan,
1036                                                                  true, false);
1037                         }
1038                 } else {
1039                         /*
1040                          * If we failed to insert promiscuous filters, don't
1041                          * rollback.  Regardless, also insert the mc_list,
1042                          * unless it's incomplete due to overflow
1043                          */
1044                         efx_mcdi_filter_insert_def(efx, vlan,
1045                                                    EFX_ENCAP_TYPE_NONE,
1046                                                    true, false);
1047                         if (!table->mc_overflow)
1048                                 efx_mcdi_filter_insert_addr_list(efx, vlan,
1049                                                                  true, false);
1050                 }
1051         } else {
1052                 /*
1053                  * If any filters failed to insert, rollback and fall back to
1054                  * promiscuous mode - mc_def filter and maybe broadcast.  If
1055                  * that fails, roll back again and insert as many of our
1056                  * individual multicast filters as we can.
1057                  */
1058                 if (efx_mcdi_filter_insert_addr_list(efx, vlan, true, true)) {
1059                         /* Changing promisc state, so remove old filters */
1060                         if (table->mc_chaining)
1061                                 efx_mcdi_filter_remove_old(efx);
1062                         if (efx_mcdi_filter_insert_def(efx, vlan,
1063                                                        EFX_ENCAP_TYPE_NONE,
1064                                                        true, true))
1065                                 efx_mcdi_filter_insert_addr_list(efx, vlan,
1066                                                                  true, false);
1067                 }
1068         }
1069         efx_mcdi_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_VXLAN,
1070                                    true, false);
1071         efx_mcdi_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_VXLAN |
1072                                               EFX_ENCAP_FLAG_IPV6,
1073                                    true, false);
1074         efx_mcdi_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_NVGRE,
1075                                    true, false);
1076         efx_mcdi_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_NVGRE |
1077                                               EFX_ENCAP_FLAG_IPV6,
1078                                    true, false);
1079         efx_mcdi_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_GENEVE,
1080                                    true, false);
1081         efx_mcdi_filter_insert_def(efx, vlan, EFX_ENCAP_TYPE_GENEVE |
1082                                               EFX_ENCAP_FLAG_IPV6,
1083                                    true, false);
1084 }
1085
1086 int efx_mcdi_filter_clear_rx(struct efx_nic *efx,
1087                              enum efx_filter_priority priority)
1088 {
1089         struct efx_mcdi_filter_table *table;
1090         unsigned int priority_mask;
1091         unsigned int i;
1092         int rc;
1093
1094         priority_mask = (((1U << (priority + 1)) - 1) &
1095                          ~(1U << EFX_FILTER_PRI_AUTO));
1096
1097         down_read(&efx->filter_sem);
1098         table = efx->filter_state;
1099         down_write(&table->lock);
1100         for (i = 0; i < EFX_MCDI_FILTER_TBL_ROWS; i++) {
1101                 rc = efx_mcdi_filter_remove_internal(efx, priority_mask,
1102                                                      i, true);
1103                 if (rc && rc != -ENOENT)
1104                         break;
1105                 rc = 0;
1106         }
1107
1108         up_write(&table->lock);
1109         up_read(&efx->filter_sem);
1110         return rc;
1111 }
1112
1113 u32 efx_mcdi_filter_count_rx_used(struct efx_nic *efx,
1114                                  enum efx_filter_priority priority)
1115 {
1116         struct efx_mcdi_filter_table *table;
1117         unsigned int filter_idx;
1118         s32 count = 0;
1119
1120         down_read(&efx->filter_sem);
1121         table = efx->filter_state;
1122         down_read(&table->lock);
1123         for (filter_idx = 0; filter_idx < EFX_MCDI_FILTER_TBL_ROWS; filter_idx++) {
1124                 if (table->entry[filter_idx].spec &&
1125                     efx_mcdi_filter_entry_spec(table, filter_idx)->priority ==
1126                     priority)
1127                         ++count;
1128         }
1129         up_read(&table->lock);
1130         up_read(&efx->filter_sem);
1131         return count;
1132 }
1133
1134 u32 efx_mcdi_filter_get_rx_id_limit(struct efx_nic *efx)
1135 {
1136         struct efx_mcdi_filter_table *table = efx->filter_state;
1137
1138         return table->rx_match_count * EFX_MCDI_FILTER_TBL_ROWS * 2;
1139 }
1140
1141 s32 efx_mcdi_filter_get_rx_ids(struct efx_nic *efx,
1142                                enum efx_filter_priority priority,
1143                                u32 *buf, u32 size)
1144 {
1145         struct efx_mcdi_filter_table *table;
1146         struct efx_filter_spec *spec;
1147         unsigned int filter_idx;
1148         s32 count = 0;
1149
1150         down_read(&efx->filter_sem);
1151         table = efx->filter_state;
1152         down_read(&table->lock);
1153
1154         for (filter_idx = 0; filter_idx < EFX_MCDI_FILTER_TBL_ROWS; filter_idx++) {
1155                 spec = efx_mcdi_filter_entry_spec(table, filter_idx);
1156                 if (spec && spec->priority == priority) {
1157                         if (count == size) {
1158                                 count = -EMSGSIZE;
1159                                 break;
1160                         }
1161                         buf[count++] =
1162                                 efx_mcdi_filter_make_filter_id(
1163                                         efx_mcdi_filter_pri(table, spec),
1164                                         filter_idx);
1165                 }
1166         }
1167         up_read(&table->lock);
1168         up_read(&efx->filter_sem);
1169         return count;
1170 }
1171
1172 static int efx_mcdi_filter_match_flags_from_mcdi(bool encap, u32 mcdi_flags)
1173 {
1174         int match_flags = 0;
1175
1176 #define MAP_FLAG(gen_flag, mcdi_field) do {                             \
1177                 u32 old_mcdi_flags = mcdi_flags;                        \
1178                 mcdi_flags &= ~(1 << MC_CMD_FILTER_OP_EXT_IN_MATCH_ ##  \
1179                                      mcdi_field ## _LBN);               \
1180                 if (mcdi_flags != old_mcdi_flags)                       \
1181                         match_flags |= EFX_FILTER_MATCH_ ## gen_flag;   \
1182         } while (0)
1183
1184         if (encap) {
1185                 /* encap filters must specify encap type */
1186                 match_flags |= EFX_FILTER_MATCH_ENCAP_TYPE;
1187                 /* and imply ethertype and ip proto */
1188                 mcdi_flags &=
1189                         ~(1 << MC_CMD_FILTER_OP_EXT_IN_MATCH_IP_PROTO_LBN);
1190                 mcdi_flags &=
1191                         ~(1 << MC_CMD_FILTER_OP_EXT_IN_MATCH_ETHER_TYPE_LBN);
1192                 /* VLAN tags refer to the outer packet */
1193                 MAP_FLAG(INNER_VID, INNER_VLAN);
1194                 MAP_FLAG(OUTER_VID, OUTER_VLAN);
1195                 /* everything else refers to the inner packet */
1196                 MAP_FLAG(LOC_MAC_IG, IFRM_UNKNOWN_UCAST_DST);
1197                 MAP_FLAG(LOC_MAC_IG, IFRM_UNKNOWN_MCAST_DST);
1198                 MAP_FLAG(REM_HOST, IFRM_SRC_IP);
1199                 MAP_FLAG(LOC_HOST, IFRM_DST_IP);
1200                 MAP_FLAG(REM_MAC, IFRM_SRC_MAC);
1201                 MAP_FLAG(REM_PORT, IFRM_SRC_PORT);
1202                 MAP_FLAG(LOC_MAC, IFRM_DST_MAC);
1203                 MAP_FLAG(LOC_PORT, IFRM_DST_PORT);
1204                 MAP_FLAG(ETHER_TYPE, IFRM_ETHER_TYPE);
1205                 MAP_FLAG(IP_PROTO, IFRM_IP_PROTO);
1206         } else {
1207                 MAP_FLAG(LOC_MAC_IG, UNKNOWN_UCAST_DST);
1208                 MAP_FLAG(LOC_MAC_IG, UNKNOWN_MCAST_DST);
1209                 MAP_FLAG(REM_HOST, SRC_IP);
1210                 MAP_FLAG(LOC_HOST, DST_IP);
1211                 MAP_FLAG(REM_MAC, SRC_MAC);
1212                 MAP_FLAG(REM_PORT, SRC_PORT);
1213                 MAP_FLAG(LOC_MAC, DST_MAC);
1214                 MAP_FLAG(LOC_PORT, DST_PORT);
1215                 MAP_FLAG(ETHER_TYPE, ETHER_TYPE);
1216                 MAP_FLAG(INNER_VID, INNER_VLAN);
1217                 MAP_FLAG(OUTER_VID, OUTER_VLAN);
1218                 MAP_FLAG(IP_PROTO, IP_PROTO);
1219         }
1220 #undef MAP_FLAG
1221
1222         /* Did we map them all? */
1223         if (mcdi_flags)
1224                 return -EINVAL;
1225
1226         return match_flags;
1227 }
1228
1229 bool efx_mcdi_filter_match_supported(struct efx_mcdi_filter_table *table,
1230                                      bool encap,
1231                                      enum efx_filter_match_flags match_flags)
1232 {
1233         unsigned int match_pri;
1234         int mf;
1235
1236         for (match_pri = 0;
1237              match_pri < table->rx_match_count;
1238              match_pri++) {
1239                 mf = efx_mcdi_filter_match_flags_from_mcdi(encap,
1240                                 table->rx_match_mcdi_flags[match_pri]);
1241                 if (mf == match_flags)
1242                         return true;
1243         }
1244
1245         return false;
1246 }
1247
1248 static int
1249 efx_mcdi_filter_table_probe_matches(struct efx_nic *efx,
1250                                     struct efx_mcdi_filter_table *table,
1251                                     bool encap)
1252 {
1253         MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_PARSER_DISP_INFO_IN_LEN);
1254         MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX);
1255         unsigned int pd_match_pri, pd_match_count;
1256         size_t outlen;
1257         int rc;
1258
1259         /* Find out which RX filter types are supported, and their priorities */
1260         MCDI_SET_DWORD(inbuf, GET_PARSER_DISP_INFO_IN_OP,
1261                        encap ?
1262                        MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_ENCAP_RX_MATCHES :
1263                        MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_RX_MATCHES);
1264         rc = efx_mcdi_rpc(efx, MC_CMD_GET_PARSER_DISP_INFO,
1265                           inbuf, sizeof(inbuf), outbuf, sizeof(outbuf),
1266                           &outlen);
1267         if (rc)
1268                 return rc;
1269
1270         pd_match_count = MCDI_VAR_ARRAY_LEN(
1271                 outlen, GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES);
1272
1273         for (pd_match_pri = 0; pd_match_pri < pd_match_count; pd_match_pri++) {
1274                 u32 mcdi_flags =
1275                         MCDI_ARRAY_DWORD(
1276                                 outbuf,
1277                                 GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES,
1278                                 pd_match_pri);
1279                 rc = efx_mcdi_filter_match_flags_from_mcdi(encap, mcdi_flags);
1280                 if (rc < 0) {
1281                         netif_dbg(efx, probe, efx->net_dev,
1282                                   "%s: fw flags %#x pri %u not supported in driver\n",
1283                                   __func__, mcdi_flags, pd_match_pri);
1284                 } else {
1285                         netif_dbg(efx, probe, efx->net_dev,
1286                                   "%s: fw flags %#x pri %u supported as driver flags %#x pri %u\n",
1287                                   __func__, mcdi_flags, pd_match_pri,
1288                                   rc, table->rx_match_count);
1289                         table->rx_match_mcdi_flags[table->rx_match_count] = mcdi_flags;
1290                         table->rx_match_count++;
1291                 }
1292         }
1293
1294         return 0;
1295 }
1296
1297 int efx_mcdi_filter_table_probe(struct efx_nic *efx, bool multicast_chaining)
1298 {
1299         struct net_device *net_dev = efx->net_dev;
1300         struct efx_mcdi_filter_table *table;
1301         int rc;
1302
1303         if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
1304                 return -EINVAL;
1305
1306         if (efx->filter_state) /* already probed */
1307                 return 0;
1308
1309         table = kzalloc(sizeof(*table), GFP_KERNEL);
1310         if (!table)
1311                 return -ENOMEM;
1312
1313         table->mc_chaining = multicast_chaining;
1314         table->rx_match_count = 0;
1315         rc = efx_mcdi_filter_table_probe_matches(efx, table, false);
1316         if (rc)
1317                 goto fail;
1318         if (efx_has_cap(efx, VXLAN_NVGRE))
1319                 rc = efx_mcdi_filter_table_probe_matches(efx, table, true);
1320         if (rc)
1321                 goto fail;
1322         if ((efx_supported_features(efx) & NETIF_F_HW_VLAN_CTAG_FILTER) &&
1323             !(efx_mcdi_filter_match_supported(table, false,
1324                 (EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_LOC_MAC)) &&
1325               efx_mcdi_filter_match_supported(table, false,
1326                 (EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_LOC_MAC_IG)))) {
1327                 netif_info(efx, probe, net_dev,
1328                            "VLAN filters are not supported in this firmware variant\n");
1329                 net_dev->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
1330                 efx->fixed_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
1331                 net_dev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
1332         }
1333
1334         table->entry = vzalloc(array_size(EFX_MCDI_FILTER_TBL_ROWS,
1335                                           sizeof(*table->entry)));
1336         if (!table->entry) {
1337                 rc = -ENOMEM;
1338                 goto fail;
1339         }
1340
1341         table->mc_promisc_last = false;
1342         table->vlan_filter =
1343                 !!(efx->net_dev->features & NETIF_F_HW_VLAN_CTAG_FILTER);
1344         INIT_LIST_HEAD(&table->vlan_list);
1345         init_rwsem(&table->lock);
1346
1347         efx->filter_state = table;
1348
1349         return 0;
1350 fail:
1351         kfree(table);
1352         return rc;
1353 }
1354
1355 void efx_mcdi_filter_table_reset_mc_allocations(struct efx_nic *efx)
1356 {
1357         struct efx_mcdi_filter_table *table = efx->filter_state;
1358
1359         if (table) {
1360                 table->must_restore_filters = true;
1361                 table->must_restore_rss_contexts = true;
1362         }
1363 }
1364
1365 /*
1366  * Caller must hold efx->filter_sem for read if race against
1367  * efx_mcdi_filter_table_remove() is possible
1368  */
1369 void efx_mcdi_filter_table_restore(struct efx_nic *efx)
1370 {
1371         struct efx_mcdi_filter_table *table = efx->filter_state;
1372         unsigned int invalid_filters = 0, failed = 0;
1373         struct efx_mcdi_filter_vlan *vlan;
1374         struct efx_filter_spec *spec;
1375         struct efx_rss_context *ctx;
1376         unsigned int filter_idx;
1377         u32 mcdi_flags;
1378         int match_pri;
1379         int rc, i;
1380
1381         WARN_ON(!rwsem_is_locked(&efx->filter_sem));
1382
1383         if (!table || !table->must_restore_filters)
1384                 return;
1385
1386         down_write(&table->lock);
1387         mutex_lock(&efx->rss_lock);
1388
1389         for (filter_idx = 0; filter_idx < EFX_MCDI_FILTER_TBL_ROWS; filter_idx++) {
1390                 spec = efx_mcdi_filter_entry_spec(table, filter_idx);
1391                 if (!spec)
1392                         continue;
1393
1394                 mcdi_flags = efx_mcdi_filter_mcdi_flags_from_spec(spec);
1395                 match_pri = 0;
1396                 while (match_pri < table->rx_match_count &&
1397                        table->rx_match_mcdi_flags[match_pri] != mcdi_flags)
1398                         ++match_pri;
1399                 if (match_pri >= table->rx_match_count) {
1400                         invalid_filters++;
1401                         goto not_restored;
1402                 }
1403                 if (spec->rss_context)
1404                         ctx = efx_find_rss_context_entry(efx, spec->rss_context);
1405                 else
1406                         ctx = &efx->rss_context;
1407                 if (spec->flags & EFX_FILTER_FLAG_RX_RSS) {
1408                         if (!ctx) {
1409                                 netif_warn(efx, drv, efx->net_dev,
1410                                            "Warning: unable to restore a filter with nonexistent RSS context %u.\n",
1411                                            spec->rss_context);
1412                                 invalid_filters++;
1413                                 goto not_restored;
1414                         }
1415                         if (ctx->context_id == EFX_MCDI_RSS_CONTEXT_INVALID) {
1416                                 netif_warn(efx, drv, efx->net_dev,
1417                                            "Warning: unable to restore a filter with RSS context %u as it was not created.\n",
1418                                            spec->rss_context);
1419                                 invalid_filters++;
1420                                 goto not_restored;
1421                         }
1422                 }
1423
1424                 rc = efx_mcdi_filter_push(efx, spec,
1425                                           &table->entry[filter_idx].handle,
1426                                           ctx, false);
1427                 if (rc)
1428                         failed++;
1429
1430                 if (rc) {
1431 not_restored:
1432                         list_for_each_entry(vlan, &table->vlan_list, list)
1433                                 for (i = 0; i < EFX_EF10_NUM_DEFAULT_FILTERS; ++i)
1434                                         if (vlan->default_filters[i] == filter_idx)
1435                                                 vlan->default_filters[i] =
1436                                                         EFX_EF10_FILTER_ID_INVALID;
1437
1438                         kfree(spec);
1439                         efx_mcdi_filter_set_entry(table, filter_idx, NULL, 0);
1440                 }
1441         }
1442
1443         mutex_unlock(&efx->rss_lock);
1444         up_write(&table->lock);
1445
1446         /*
1447          * This can happen validly if the MC's capabilities have changed, so
1448          * is not an error.
1449          */
1450         if (invalid_filters)
1451                 netif_dbg(efx, drv, efx->net_dev,
1452                           "Did not restore %u filters that are now unsupported.\n",
1453                           invalid_filters);
1454
1455         if (failed)
1456                 netif_err(efx, hw, efx->net_dev,
1457                           "unable to restore %u filters\n", failed);
1458         else
1459                 table->must_restore_filters = false;
1460 }
1461
1462 void efx_mcdi_filter_table_down(struct efx_nic *efx)
1463 {
1464         struct efx_mcdi_filter_table *table = efx->filter_state;
1465         MCDI_DECLARE_BUF(inbuf, MC_CMD_FILTER_OP_EXT_IN_LEN);
1466         struct efx_filter_spec *spec;
1467         unsigned int filter_idx;
1468         int rc;
1469
1470         if (!table)
1471                 return;
1472
1473         efx_mcdi_filter_cleanup_vlans(efx);
1474
1475         for (filter_idx = 0; filter_idx < EFX_MCDI_FILTER_TBL_ROWS; filter_idx++) {
1476                 spec = efx_mcdi_filter_entry_spec(table, filter_idx);
1477                 if (!spec)
1478                         continue;
1479
1480                 MCDI_SET_DWORD(inbuf, FILTER_OP_IN_OP,
1481                                efx_mcdi_filter_is_exclusive(spec) ?
1482                                MC_CMD_FILTER_OP_IN_OP_REMOVE :
1483                                MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE);
1484                 MCDI_SET_QWORD(inbuf, FILTER_OP_IN_HANDLE,
1485                                table->entry[filter_idx].handle);
1486                 rc = efx_mcdi_rpc_quiet(efx, MC_CMD_FILTER_OP, inbuf,
1487                                         sizeof(inbuf), NULL, 0, NULL);
1488                 if (rc)
1489                         netif_info(efx, drv, efx->net_dev,
1490                                    "%s: filter %04x remove failed\n",
1491                                    __func__, filter_idx);
1492                 kfree(spec);
1493         }
1494 }
1495
1496 void efx_mcdi_filter_table_remove(struct efx_nic *efx)
1497 {
1498         struct efx_mcdi_filter_table *table = efx->filter_state;
1499
1500         efx_mcdi_filter_table_down(efx);
1501
1502         efx->filter_state = NULL;
1503         /*
1504          * If we were called without locking, then it's not safe to free
1505          * the table as others might be using it.  So we just WARN, leak
1506          * the memory, and potentially get an inconsistent filter table
1507          * state.
1508          * This should never actually happen.
1509          */
1510         if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
1511                 return;
1512
1513         if (!table)
1514                 return;
1515
1516         vfree(table->entry);
1517         kfree(table);
1518 }
1519
1520 static void efx_mcdi_filter_mark_one_old(struct efx_nic *efx, uint16_t *id)
1521 {
1522         struct efx_mcdi_filter_table *table = efx->filter_state;
1523         unsigned int filter_idx;
1524
1525         efx_rwsem_assert_write_locked(&table->lock);
1526
1527         if (*id != EFX_EF10_FILTER_ID_INVALID) {
1528                 filter_idx = efx_mcdi_filter_get_unsafe_id(*id);
1529                 if (!table->entry[filter_idx].spec)
1530                         netif_dbg(efx, drv, efx->net_dev,
1531                                   "marked null spec old %04x:%04x\n", *id,
1532                                   filter_idx);
1533                 table->entry[filter_idx].spec |= EFX_EF10_FILTER_FLAG_AUTO_OLD;
1534                 *id = EFX_EF10_FILTER_ID_INVALID;
1535         }
1536 }
1537
1538 /* Mark old per-VLAN filters that may need to be removed */
1539 static void _efx_mcdi_filter_vlan_mark_old(struct efx_nic *efx,
1540                                            struct efx_mcdi_filter_vlan *vlan)
1541 {
1542         struct efx_mcdi_filter_table *table = efx->filter_state;
1543         unsigned int i;
1544
1545         for (i = 0; i < table->dev_uc_count; i++)
1546                 efx_mcdi_filter_mark_one_old(efx, &vlan->uc[i]);
1547         for (i = 0; i < table->dev_mc_count; i++)
1548                 efx_mcdi_filter_mark_one_old(efx, &vlan->mc[i]);
1549         for (i = 0; i < EFX_EF10_NUM_DEFAULT_FILTERS; i++)
1550                 efx_mcdi_filter_mark_one_old(efx, &vlan->default_filters[i]);
1551 }
1552
1553 /*
1554  * Mark old filters that may need to be removed.
1555  * Caller must hold efx->filter_sem for read if race against
1556  * efx_mcdi_filter_table_remove() is possible
1557  */
1558 static void efx_mcdi_filter_mark_old(struct efx_nic *efx)
1559 {
1560         struct efx_mcdi_filter_table *table = efx->filter_state;
1561         struct efx_mcdi_filter_vlan *vlan;
1562
1563         down_write(&table->lock);
1564         list_for_each_entry(vlan, &table->vlan_list, list)
1565                 _efx_mcdi_filter_vlan_mark_old(efx, vlan);
1566         up_write(&table->lock);
1567 }
1568
1569 int efx_mcdi_filter_add_vlan(struct efx_nic *efx, u16 vid)
1570 {
1571         struct efx_mcdi_filter_table *table = efx->filter_state;
1572         struct efx_mcdi_filter_vlan *vlan;
1573         unsigned int i;
1574
1575         if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
1576                 return -EINVAL;
1577
1578         vlan = efx_mcdi_filter_find_vlan(efx, vid);
1579         if (WARN_ON(vlan)) {
1580                 netif_err(efx, drv, efx->net_dev,
1581                           "VLAN %u already added\n", vid);
1582                 return -EALREADY;
1583         }
1584
1585         vlan = kzalloc(sizeof(*vlan), GFP_KERNEL);
1586         if (!vlan)
1587                 return -ENOMEM;
1588
1589         vlan->vid = vid;
1590
1591         for (i = 0; i < ARRAY_SIZE(vlan->uc); i++)
1592                 vlan->uc[i] = EFX_EF10_FILTER_ID_INVALID;
1593         for (i = 0; i < ARRAY_SIZE(vlan->mc); i++)
1594                 vlan->mc[i] = EFX_EF10_FILTER_ID_INVALID;
1595         for (i = 0; i < EFX_EF10_NUM_DEFAULT_FILTERS; i++)
1596                 vlan->default_filters[i] = EFX_EF10_FILTER_ID_INVALID;
1597
1598         list_add_tail(&vlan->list, &table->vlan_list);
1599
1600         if (efx_dev_registered(efx))
1601                 efx_mcdi_filter_vlan_sync_rx_mode(efx, vlan);
1602
1603         return 0;
1604 }
1605
1606 static void efx_mcdi_filter_del_vlan_internal(struct efx_nic *efx,
1607                                               struct efx_mcdi_filter_vlan *vlan)
1608 {
1609         unsigned int i;
1610
1611         /* See comment in efx_mcdi_filter_table_remove() */
1612         if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
1613                 return;
1614
1615         list_del(&vlan->list);
1616
1617         for (i = 0; i < ARRAY_SIZE(vlan->uc); i++)
1618                 efx_mcdi_filter_remove_unsafe(efx, EFX_FILTER_PRI_AUTO,
1619                                               vlan->uc[i]);
1620         for (i = 0; i < ARRAY_SIZE(vlan->mc); i++)
1621                 efx_mcdi_filter_remove_unsafe(efx, EFX_FILTER_PRI_AUTO,
1622                                               vlan->mc[i]);
1623         for (i = 0; i < EFX_EF10_NUM_DEFAULT_FILTERS; i++)
1624                 if (vlan->default_filters[i] != EFX_EF10_FILTER_ID_INVALID)
1625                         efx_mcdi_filter_remove_unsafe(efx, EFX_FILTER_PRI_AUTO,
1626                                                       vlan->default_filters[i]);
1627
1628         kfree(vlan);
1629 }
1630
1631 void efx_mcdi_filter_del_vlan(struct efx_nic *efx, u16 vid)
1632 {
1633         struct efx_mcdi_filter_vlan *vlan;
1634
1635         /* See comment in efx_mcdi_filter_table_remove() */
1636         if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
1637                 return;
1638
1639         vlan = efx_mcdi_filter_find_vlan(efx, vid);
1640         if (!vlan) {
1641                 netif_err(efx, drv, efx->net_dev,
1642                           "VLAN %u not found in filter state\n", vid);
1643                 return;
1644         }
1645
1646         efx_mcdi_filter_del_vlan_internal(efx, vlan);
1647 }
1648
1649 struct efx_mcdi_filter_vlan *efx_mcdi_filter_find_vlan(struct efx_nic *efx,
1650                                                        u16 vid)
1651 {
1652         struct efx_mcdi_filter_table *table = efx->filter_state;
1653         struct efx_mcdi_filter_vlan *vlan;
1654
1655         WARN_ON(!rwsem_is_locked(&efx->filter_sem));
1656
1657         list_for_each_entry(vlan, &table->vlan_list, list) {
1658                 if (vlan->vid == vid)
1659                         return vlan;
1660         }
1661
1662         return NULL;
1663 }
1664
1665 void efx_mcdi_filter_cleanup_vlans(struct efx_nic *efx)
1666 {
1667         struct efx_mcdi_filter_table *table = efx->filter_state;
1668         struct efx_mcdi_filter_vlan *vlan, *next_vlan;
1669
1670         /* See comment in efx_mcdi_filter_table_remove() */
1671         if (!efx_rwsem_assert_write_locked(&efx->filter_sem))
1672                 return;
1673
1674         if (!table)
1675                 return;
1676
1677         list_for_each_entry_safe(vlan, next_vlan, &table->vlan_list, list)
1678                 efx_mcdi_filter_del_vlan_internal(efx, vlan);
1679 }
1680
1681 static void efx_mcdi_filter_uc_addr_list(struct efx_nic *efx)
1682 {
1683         struct efx_mcdi_filter_table *table = efx->filter_state;
1684         struct net_device *net_dev = efx->net_dev;
1685         struct netdev_hw_addr *uc;
1686         unsigned int i;
1687
1688         table->uc_promisc = !!(net_dev->flags & IFF_PROMISC);
1689         ether_addr_copy(table->dev_uc_list[0].addr, net_dev->dev_addr);
1690         i = 1;
1691         netdev_for_each_uc_addr(uc, net_dev) {
1692                 if (i >= EFX_EF10_FILTER_DEV_UC_MAX) {
1693                         table->uc_promisc = true;
1694                         break;
1695                 }
1696                 ether_addr_copy(table->dev_uc_list[i].addr, uc->addr);
1697                 i++;
1698         }
1699
1700         table->dev_uc_count = i;
1701 }
1702
1703 static void efx_mcdi_filter_mc_addr_list(struct efx_nic *efx)
1704 {
1705         struct efx_mcdi_filter_table *table = efx->filter_state;
1706         struct net_device *net_dev = efx->net_dev;
1707         struct netdev_hw_addr *mc;
1708         unsigned int i;
1709
1710         table->mc_overflow = false;
1711         table->mc_promisc = !!(net_dev->flags & (IFF_PROMISC | IFF_ALLMULTI));
1712
1713         i = 0;
1714         netdev_for_each_mc_addr(mc, net_dev) {
1715                 if (i >= EFX_EF10_FILTER_DEV_MC_MAX) {
1716                         table->mc_promisc = true;
1717                         table->mc_overflow = true;
1718                         break;
1719                 }
1720                 ether_addr_copy(table->dev_mc_list[i].addr, mc->addr);
1721                 i++;
1722         }
1723
1724         table->dev_mc_count = i;
1725 }
1726
1727 /*
1728  * Caller must hold efx->filter_sem for read if race against
1729  * efx_mcdi_filter_table_remove() is possible
1730  */
1731 void efx_mcdi_filter_sync_rx_mode(struct efx_nic *efx)
1732 {
1733         struct efx_mcdi_filter_table *table = efx->filter_state;
1734         struct net_device *net_dev = efx->net_dev;
1735         struct efx_mcdi_filter_vlan *vlan;
1736         bool vlan_filter;
1737
1738         if (!efx_dev_registered(efx))
1739                 return;
1740
1741         if (!table)
1742                 return;
1743
1744         efx_mcdi_filter_mark_old(efx);
1745
1746         /*
1747          * Copy/convert the address lists; add the primary station
1748          * address and broadcast address
1749          */
1750         netif_addr_lock_bh(net_dev);
1751         efx_mcdi_filter_uc_addr_list(efx);
1752         efx_mcdi_filter_mc_addr_list(efx);
1753         netif_addr_unlock_bh(net_dev);
1754
1755         /*
1756          * If VLAN filtering changes, all old filters are finally removed.
1757          * Do it in advance to avoid conflicts for unicast untagged and
1758          * VLAN 0 tagged filters.
1759          */
1760         vlan_filter = !!(net_dev->features & NETIF_F_HW_VLAN_CTAG_FILTER);
1761         if (table->vlan_filter != vlan_filter) {
1762                 table->vlan_filter = vlan_filter;
1763                 efx_mcdi_filter_remove_old(efx);
1764         }
1765
1766         list_for_each_entry(vlan, &table->vlan_list, list)
1767                 efx_mcdi_filter_vlan_sync_rx_mode(efx, vlan);
1768
1769         efx_mcdi_filter_remove_old(efx);
1770         table->mc_promisc_last = table->mc_promisc;
1771 }
1772
1773 #ifdef CONFIG_RFS_ACCEL
1774
1775 bool efx_mcdi_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id,
1776                                     unsigned int filter_idx)
1777 {
1778         struct efx_filter_spec *spec, saved_spec;
1779         struct efx_mcdi_filter_table *table;
1780         struct efx_arfs_rule *rule = NULL;
1781         bool ret = true, force = false;
1782         u16 arfs_id;
1783
1784         down_read(&efx->filter_sem);
1785         table = efx->filter_state;
1786         down_write(&table->lock);
1787         spec = efx_mcdi_filter_entry_spec(table, filter_idx);
1788
1789         if (!spec || spec->priority != EFX_FILTER_PRI_HINT)
1790                 goto out_unlock;
1791
1792         spin_lock_bh(&efx->rps_hash_lock);
1793         if (!efx->rps_hash_table) {
1794                 /* In the absence of the table, we always return 0 to ARFS. */
1795                 arfs_id = 0;
1796         } else {
1797                 rule = efx_rps_hash_find(efx, spec);
1798                 if (!rule)
1799                         /* ARFS table doesn't know of this filter, so remove it */
1800                         goto expire;
1801                 arfs_id = rule->arfs_id;
1802                 ret = efx_rps_check_rule(rule, filter_idx, &force);
1803                 if (force)
1804                         goto expire;
1805                 if (!ret) {
1806                         spin_unlock_bh(&efx->rps_hash_lock);
1807                         goto out_unlock;
1808                 }
1809         }
1810         if (!rps_may_expire_flow(efx->net_dev, spec->dmaq_id, flow_id, arfs_id))
1811                 ret = false;
1812         else if (rule)
1813                 rule->filter_id = EFX_ARFS_FILTER_ID_REMOVING;
1814 expire:
1815         saved_spec = *spec; /* remove operation will kfree spec */
1816         spin_unlock_bh(&efx->rps_hash_lock);
1817         /*
1818          * At this point (since we dropped the lock), another thread might queue
1819          * up a fresh insertion request (but the actual insertion will be held
1820          * up by our possession of the filter table lock).  In that case, it
1821          * will set rule->filter_id to EFX_ARFS_FILTER_ID_PENDING, meaning that
1822          * the rule is not removed by efx_rps_hash_del() below.
1823          */
1824         if (ret)
1825                 ret = efx_mcdi_filter_remove_internal(efx, 1U << spec->priority,
1826                                                       filter_idx, true) == 0;
1827         /*
1828          * While we can't safely dereference rule (we dropped the lock), we can
1829          * still test it for NULL.
1830          */
1831         if (ret && rule) {
1832                 /* Expiring, so remove entry from ARFS table */
1833                 spin_lock_bh(&efx->rps_hash_lock);
1834                 efx_rps_hash_del(efx, &saved_spec);
1835                 spin_unlock_bh(&efx->rps_hash_lock);
1836         }
1837 out_unlock:
1838         up_write(&table->lock);
1839         up_read(&efx->filter_sem);
1840         return ret;
1841 }
1842
1843 #endif /* CONFIG_RFS_ACCEL */
1844
1845 #define RSS_MODE_HASH_ADDRS     (1 << RSS_MODE_HASH_SRC_ADDR_LBN |\
1846                                  1 << RSS_MODE_HASH_DST_ADDR_LBN)
1847 #define RSS_MODE_HASH_PORTS     (1 << RSS_MODE_HASH_SRC_PORT_LBN |\
1848                                  1 << RSS_MODE_HASH_DST_PORT_LBN)
1849 #define RSS_CONTEXT_FLAGS_DEFAULT       (1 << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV4_EN_LBN |\
1850                                          1 << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV4_EN_LBN |\
1851                                          1 << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV6_EN_LBN |\
1852                                          1 << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV6_EN_LBN |\
1853                                          (RSS_MODE_HASH_ADDRS | RSS_MODE_HASH_PORTS) << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV4_RSS_MODE_LBN |\
1854                                          RSS_MODE_HASH_ADDRS << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV4_RSS_MODE_LBN |\
1855                                          RSS_MODE_HASH_ADDRS << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV4_RSS_MODE_LBN |\
1856                                          (RSS_MODE_HASH_ADDRS | RSS_MODE_HASH_PORTS) << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV6_RSS_MODE_LBN |\
1857                                          RSS_MODE_HASH_ADDRS << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV6_RSS_MODE_LBN |\
1858                                          RSS_MODE_HASH_ADDRS << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV6_RSS_MODE_LBN)
1859
1860 int efx_mcdi_get_rss_context_flags(struct efx_nic *efx, u32 context, u32 *flags)
1861 {
1862         /*
1863          * Firmware had a bug (sfc bug 61952) where it would not actually
1864          * fill in the flags field in the response to MC_CMD_RSS_CONTEXT_GET_FLAGS.
1865          * This meant that it would always contain whatever was previously
1866          * in the MCDI buffer.  Fortunately, all firmware versions with
1867          * this bug have the same default flags value for a newly-allocated
1868          * RSS context, and the only time we want to get the flags is just
1869          * after allocating.  Moreover, the response has a 32-bit hole
1870          * where the context ID would be in the request, so we can use an
1871          * overlength buffer in the request and pre-fill the flags field
1872          * with what we believe the default to be.  Thus if the firmware
1873          * has the bug, it will leave our pre-filled value in the flags
1874          * field of the response, and we will get the right answer.
1875          *
1876          * However, this does mean that this function should NOT be used if
1877          * the RSS context flags might not be their defaults - it is ONLY
1878          * reliably correct for a newly-allocated RSS context.
1879          */
1880         MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_LEN);
1881         MCDI_DECLARE_BUF(outbuf, MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_LEN);
1882         size_t outlen;
1883         int rc;
1884
1885         /* Check we have a hole for the context ID */
1886         BUILD_BUG_ON(MC_CMD_RSS_CONTEXT_GET_FLAGS_IN_LEN != MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_FLAGS_OFST);
1887         MCDI_SET_DWORD(inbuf, RSS_CONTEXT_GET_FLAGS_IN_RSS_CONTEXT_ID, context);
1888         MCDI_SET_DWORD(inbuf, RSS_CONTEXT_GET_FLAGS_OUT_FLAGS,
1889                        RSS_CONTEXT_FLAGS_DEFAULT);
1890         rc = efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_GET_FLAGS, inbuf,
1891                           sizeof(inbuf), outbuf, sizeof(outbuf), &outlen);
1892         if (rc == 0) {
1893                 if (outlen < MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_LEN)
1894                         rc = -EIO;
1895                 else
1896                         *flags = MCDI_DWORD(outbuf, RSS_CONTEXT_GET_FLAGS_OUT_FLAGS);
1897         }
1898         return rc;
1899 }
1900
1901 /*
1902  * Attempt to enable 4-tuple UDP hashing on the specified RSS context.
1903  * If we fail, we just leave the RSS context at its default hash settings,
1904  * which is safe but may slightly reduce performance.
1905  * Defaults are 4-tuple for TCP and 2-tuple for UDP and other-IP, so we
1906  * just need to set the UDP ports flags (for both IP versions).
1907  */
1908 void efx_mcdi_set_rss_context_flags(struct efx_nic *efx,
1909                                     struct efx_rss_context *ctx)
1910 {
1911         MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN);
1912         u32 flags;
1913
1914         BUILD_BUG_ON(MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN != 0);
1915
1916         if (efx_mcdi_get_rss_context_flags(efx, ctx->context_id, &flags) != 0)
1917                 return;
1918         MCDI_SET_DWORD(inbuf, RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID,
1919                        ctx->context_id);
1920         flags |= RSS_MODE_HASH_PORTS << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV4_RSS_MODE_LBN;
1921         flags |= RSS_MODE_HASH_PORTS << MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV6_RSS_MODE_LBN;
1922         MCDI_SET_DWORD(inbuf, RSS_CONTEXT_SET_FLAGS_IN_FLAGS, flags);
1923         if (!efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_SET_FLAGS, inbuf, sizeof(inbuf),
1924                           NULL, 0, NULL))
1925                 /* Succeeded, so UDP 4-tuple is now enabled */
1926                 ctx->rx_hash_udp_4tuple = true;
1927 }
1928
1929 static int efx_mcdi_filter_alloc_rss_context(struct efx_nic *efx, bool exclusive,
1930                                              struct efx_rss_context *ctx,
1931                                              unsigned *context_size)
1932 {
1933         MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN);
1934         MCDI_DECLARE_BUF(outbuf, MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN);
1935         size_t outlen;
1936         int rc;
1937         u32 alloc_type = exclusive ?
1938                                 MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_EXCLUSIVE :
1939                                 MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_SHARED;
1940         unsigned rss_spread = exclusive ?
1941                                 efx->rss_spread :
1942                                 min(rounddown_pow_of_two(efx->rss_spread),
1943                                     EFX_EF10_MAX_SHARED_RSS_CONTEXT_SIZE);
1944
1945         if (!exclusive && rss_spread == 1) {
1946                 ctx->context_id = EFX_MCDI_RSS_CONTEXT_INVALID;
1947                 if (context_size)
1948                         *context_size = 1;
1949                 return 0;
1950         }
1951
1952         if (efx_has_cap(efx, RX_RSS_LIMITED))
1953                 return -EOPNOTSUPP;
1954
1955         MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID,
1956                        efx->vport_id);
1957         MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_TYPE, alloc_type);
1958         MCDI_SET_DWORD(inbuf, RSS_CONTEXT_ALLOC_IN_NUM_QUEUES, rss_spread);
1959
1960         rc = efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_ALLOC, inbuf, sizeof(inbuf),
1961                 outbuf, sizeof(outbuf), &outlen);
1962         if (rc != 0)
1963                 return rc;
1964
1965         if (outlen < MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN)
1966                 return -EIO;
1967
1968         ctx->context_id = MCDI_DWORD(outbuf, RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID);
1969
1970         if (context_size)
1971                 *context_size = rss_spread;
1972
1973         if (efx_has_cap(efx, ADDITIONAL_RSS_MODES))
1974                 efx_mcdi_set_rss_context_flags(efx, ctx);
1975
1976         return 0;
1977 }
1978
1979 static int efx_mcdi_filter_free_rss_context(struct efx_nic *efx, u32 context)
1980 {
1981         MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_FREE_IN_LEN);
1982
1983         MCDI_SET_DWORD(inbuf, RSS_CONTEXT_FREE_IN_RSS_CONTEXT_ID,
1984                        context);
1985         return efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_FREE, inbuf, sizeof(inbuf),
1986                             NULL, 0, NULL);
1987 }
1988
1989 static int efx_mcdi_filter_populate_rss_table(struct efx_nic *efx, u32 context,
1990                                        const u32 *rx_indir_table, const u8 *key)
1991 {
1992         MCDI_DECLARE_BUF(tablebuf, MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN);
1993         MCDI_DECLARE_BUF(keybuf, MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN);
1994         int i, rc;
1995
1996         MCDI_SET_DWORD(tablebuf, RSS_CONTEXT_SET_TABLE_IN_RSS_CONTEXT_ID,
1997                        context);
1998         BUILD_BUG_ON(ARRAY_SIZE(efx->rss_context.rx_indir_table) !=
1999                      MC_CMD_RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE_LEN);
2000
2001         /* This iterates over the length of efx->rss_context.rx_indir_table, but
2002          * copies bytes from rx_indir_table.  That's because the latter is a
2003          * pointer rather than an array, but should have the same length.
2004          * The efx->rss_context.rx_hash_key loop below is similar.
2005          */
2006         for (i = 0; i < ARRAY_SIZE(efx->rss_context.rx_indir_table); ++i)
2007                 MCDI_PTR(tablebuf,
2008                          RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE)[i] =
2009                                 (u8) rx_indir_table[i];
2010
2011         rc = efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_SET_TABLE, tablebuf,
2012                           sizeof(tablebuf), NULL, 0, NULL);
2013         if (rc != 0)
2014                 return rc;
2015
2016         MCDI_SET_DWORD(keybuf, RSS_CONTEXT_SET_KEY_IN_RSS_CONTEXT_ID,
2017                        context);
2018         BUILD_BUG_ON(ARRAY_SIZE(efx->rss_context.rx_hash_key) !=
2019                      MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN);
2020         for (i = 0; i < ARRAY_SIZE(efx->rss_context.rx_hash_key); ++i)
2021                 MCDI_PTR(keybuf, RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY)[i] = key[i];
2022
2023         return efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_SET_KEY, keybuf,
2024                             sizeof(keybuf), NULL, 0, NULL);
2025 }
2026
2027 void efx_mcdi_rx_free_indir_table(struct efx_nic *efx)
2028 {
2029         int rc;
2030
2031         if (efx->rss_context.context_id != EFX_MCDI_RSS_CONTEXT_INVALID) {
2032                 rc = efx_mcdi_filter_free_rss_context(efx, efx->rss_context.context_id);
2033                 WARN_ON(rc != 0);
2034         }
2035         efx->rss_context.context_id = EFX_MCDI_RSS_CONTEXT_INVALID;
2036 }
2037
2038 static int efx_mcdi_filter_rx_push_shared_rss_config(struct efx_nic *efx,
2039                                               unsigned *context_size)
2040 {
2041         struct efx_mcdi_filter_table *table = efx->filter_state;
2042         int rc = efx_mcdi_filter_alloc_rss_context(efx, false, &efx->rss_context,
2043                                             context_size);
2044
2045         if (rc != 0)
2046                 return rc;
2047
2048         table->rx_rss_context_exclusive = false;
2049         efx_set_default_rx_indir_table(efx, &efx->rss_context);
2050         return 0;
2051 }
2052
2053 static int efx_mcdi_filter_rx_push_exclusive_rss_config(struct efx_nic *efx,
2054                                                  const u32 *rx_indir_table,
2055                                                  const u8 *key)
2056 {
2057         struct efx_mcdi_filter_table *table = efx->filter_state;
2058         u32 old_rx_rss_context = efx->rss_context.context_id;
2059         int rc;
2060
2061         if (efx->rss_context.context_id == EFX_MCDI_RSS_CONTEXT_INVALID ||
2062             !table->rx_rss_context_exclusive) {
2063                 rc = efx_mcdi_filter_alloc_rss_context(efx, true, &efx->rss_context,
2064                                                 NULL);
2065                 if (rc == -EOPNOTSUPP)
2066                         return rc;
2067                 else if (rc != 0)
2068                         goto fail1;
2069         }
2070
2071         rc = efx_mcdi_filter_populate_rss_table(efx, efx->rss_context.context_id,
2072                                          rx_indir_table, key);
2073         if (rc != 0)
2074                 goto fail2;
2075
2076         if (efx->rss_context.context_id != old_rx_rss_context &&
2077             old_rx_rss_context != EFX_MCDI_RSS_CONTEXT_INVALID)
2078                 WARN_ON(efx_mcdi_filter_free_rss_context(efx, old_rx_rss_context) != 0);
2079         table->rx_rss_context_exclusive = true;
2080         if (rx_indir_table != efx->rss_context.rx_indir_table)
2081                 memcpy(efx->rss_context.rx_indir_table, rx_indir_table,
2082                        sizeof(efx->rss_context.rx_indir_table));
2083         if (key != efx->rss_context.rx_hash_key)
2084                 memcpy(efx->rss_context.rx_hash_key, key,
2085                        efx->type->rx_hash_key_size);
2086
2087         return 0;
2088
2089 fail2:
2090         if (old_rx_rss_context != efx->rss_context.context_id) {
2091                 WARN_ON(efx_mcdi_filter_free_rss_context(efx, efx->rss_context.context_id) != 0);
2092                 efx->rss_context.context_id = old_rx_rss_context;
2093         }
2094 fail1:
2095         netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc);
2096         return rc;
2097 }
2098
2099 int efx_mcdi_rx_push_rss_context_config(struct efx_nic *efx,
2100                                         struct efx_rss_context *ctx,
2101                                         const u32 *rx_indir_table,
2102                                         const u8 *key)
2103 {
2104         int rc;
2105
2106         WARN_ON(!mutex_is_locked(&efx->rss_lock));
2107
2108         if (ctx->context_id == EFX_MCDI_RSS_CONTEXT_INVALID) {
2109                 rc = efx_mcdi_filter_alloc_rss_context(efx, true, ctx, NULL);
2110                 if (rc)
2111                         return rc;
2112         }
2113
2114         if (!rx_indir_table) /* Delete this context */
2115                 return efx_mcdi_filter_free_rss_context(efx, ctx->context_id);
2116
2117         rc = efx_mcdi_filter_populate_rss_table(efx, ctx->context_id,
2118                                          rx_indir_table, key);
2119         if (rc)
2120                 return rc;
2121
2122         memcpy(ctx->rx_indir_table, rx_indir_table,
2123                sizeof(efx->rss_context.rx_indir_table));
2124         memcpy(ctx->rx_hash_key, key, efx->type->rx_hash_key_size);
2125
2126         return 0;
2127 }
2128
2129 int efx_mcdi_rx_pull_rss_context_config(struct efx_nic *efx,
2130                                         struct efx_rss_context *ctx)
2131 {
2132         MCDI_DECLARE_BUF(inbuf, MC_CMD_RSS_CONTEXT_GET_TABLE_IN_LEN);
2133         MCDI_DECLARE_BUF(tablebuf, MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_LEN);
2134         MCDI_DECLARE_BUF(keybuf, MC_CMD_RSS_CONTEXT_GET_KEY_OUT_LEN);
2135         size_t outlen;
2136         int rc, i;
2137
2138         WARN_ON(!mutex_is_locked(&efx->rss_lock));
2139
2140         BUILD_BUG_ON(MC_CMD_RSS_CONTEXT_GET_TABLE_IN_LEN !=
2141                      MC_CMD_RSS_CONTEXT_GET_KEY_IN_LEN);
2142
2143         if (ctx->context_id == EFX_MCDI_RSS_CONTEXT_INVALID)
2144                 return -ENOENT;
2145
2146         MCDI_SET_DWORD(inbuf, RSS_CONTEXT_GET_TABLE_IN_RSS_CONTEXT_ID,
2147                        ctx->context_id);
2148         BUILD_BUG_ON(ARRAY_SIZE(ctx->rx_indir_table) !=
2149                      MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_INDIRECTION_TABLE_LEN);
2150         rc = efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_GET_TABLE, inbuf, sizeof(inbuf),
2151                           tablebuf, sizeof(tablebuf), &outlen);
2152         if (rc != 0)
2153                 return rc;
2154
2155         if (WARN_ON(outlen != MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_LEN))
2156                 return -EIO;
2157
2158         for (i = 0; i < ARRAY_SIZE(ctx->rx_indir_table); i++)
2159                 ctx->rx_indir_table[i] = MCDI_PTR(tablebuf,
2160                                 RSS_CONTEXT_GET_TABLE_OUT_INDIRECTION_TABLE)[i];
2161
2162         MCDI_SET_DWORD(inbuf, RSS_CONTEXT_GET_KEY_IN_RSS_CONTEXT_ID,
2163                        ctx->context_id);
2164         BUILD_BUG_ON(ARRAY_SIZE(ctx->rx_hash_key) !=
2165                      MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN);
2166         rc = efx_mcdi_rpc(efx, MC_CMD_RSS_CONTEXT_GET_KEY, inbuf, sizeof(inbuf),
2167                           keybuf, sizeof(keybuf), &outlen);
2168         if (rc != 0)
2169                 return rc;
2170
2171         if (WARN_ON(outlen != MC_CMD_RSS_CONTEXT_GET_KEY_OUT_LEN))
2172                 return -EIO;
2173
2174         for (i = 0; i < ARRAY_SIZE(ctx->rx_hash_key); ++i)
2175                 ctx->rx_hash_key[i] = MCDI_PTR(
2176                                 keybuf, RSS_CONTEXT_GET_KEY_OUT_TOEPLITZ_KEY)[i];
2177
2178         return 0;
2179 }
2180
2181 int efx_mcdi_rx_pull_rss_config(struct efx_nic *efx)
2182 {
2183         int rc;
2184
2185         mutex_lock(&efx->rss_lock);
2186         rc = efx_mcdi_rx_pull_rss_context_config(efx, &efx->rss_context);
2187         mutex_unlock(&efx->rss_lock);
2188         return rc;
2189 }
2190
2191 void efx_mcdi_rx_restore_rss_contexts(struct efx_nic *efx)
2192 {
2193         struct efx_mcdi_filter_table *table = efx->filter_state;
2194         struct efx_rss_context *ctx;
2195         int rc;
2196
2197         WARN_ON(!mutex_is_locked(&efx->rss_lock));
2198
2199         if (!table->must_restore_rss_contexts)
2200                 return;
2201
2202         list_for_each_entry(ctx, &efx->rss_context.list, list) {
2203                 /* previous NIC RSS context is gone */
2204                 ctx->context_id = EFX_MCDI_RSS_CONTEXT_INVALID;
2205                 /* so try to allocate a new one */
2206                 rc = efx_mcdi_rx_push_rss_context_config(efx, ctx,
2207                                                          ctx->rx_indir_table,
2208                                                          ctx->rx_hash_key);
2209                 if (rc)
2210                         netif_warn(efx, probe, efx->net_dev,
2211                                    "failed to restore RSS context %u, rc=%d"
2212                                    "; RSS filters may fail to be applied\n",
2213                                    ctx->user_id, rc);
2214         }
2215         table->must_restore_rss_contexts = false;
2216 }
2217
2218 int efx_mcdi_pf_rx_push_rss_config(struct efx_nic *efx, bool user,
2219                                    const u32 *rx_indir_table,
2220                                    const u8 *key)
2221 {
2222         int rc;
2223
2224         if (efx->rss_spread == 1)
2225                 return 0;
2226
2227         if (!key)
2228                 key = efx->rss_context.rx_hash_key;
2229
2230         rc = efx_mcdi_filter_rx_push_exclusive_rss_config(efx, rx_indir_table, key);
2231
2232         if (rc == -ENOBUFS && !user) {
2233                 unsigned context_size;
2234                 bool mismatch = false;
2235                 size_t i;
2236
2237                 for (i = 0;
2238                      i < ARRAY_SIZE(efx->rss_context.rx_indir_table) && !mismatch;
2239                      i++)
2240                         mismatch = rx_indir_table[i] !=
2241                                 ethtool_rxfh_indir_default(i, efx->rss_spread);
2242
2243                 rc = efx_mcdi_filter_rx_push_shared_rss_config(efx, &context_size);
2244                 if (rc == 0) {
2245                         if (context_size != efx->rss_spread)
2246                                 netif_warn(efx, probe, efx->net_dev,
2247                                            "Could not allocate an exclusive RSS"
2248                                            " context; allocated a shared one of"
2249                                            " different size."
2250                                            " Wanted %u, got %u.\n",
2251                                            efx->rss_spread, context_size);
2252                         else if (mismatch)
2253                                 netif_warn(efx, probe, efx->net_dev,
2254                                            "Could not allocate an exclusive RSS"
2255                                            " context; allocated a shared one but"
2256                                            " could not apply custom"
2257                                            " indirection.\n");
2258                         else
2259                                 netif_info(efx, probe, efx->net_dev,
2260                                            "Could not allocate an exclusive RSS"
2261                                            " context; allocated a shared one.\n");
2262                 }
2263         }
2264         return rc;
2265 }
2266
2267 int efx_mcdi_vf_rx_push_rss_config(struct efx_nic *efx, bool user,
2268                                    const u32 *rx_indir_table
2269                                    __attribute__ ((unused)),
2270                                    const u8 *key
2271                                    __attribute__ ((unused)))
2272 {
2273         if (user)
2274                 return -EOPNOTSUPP;
2275         if (efx->rss_context.context_id != EFX_MCDI_RSS_CONTEXT_INVALID)
2276                 return 0;
2277         return efx_mcdi_filter_rx_push_shared_rss_config(efx, NULL);
2278 }
2279
2280 int efx_mcdi_push_default_indir_table(struct efx_nic *efx,
2281                                       unsigned int rss_spread)
2282 {
2283         int rc = 0;
2284
2285         if (efx->rss_spread == rss_spread)
2286                 return 0;
2287
2288         efx->rss_spread = rss_spread;
2289         if (!efx->filter_state)
2290                 return 0;
2291
2292         efx_mcdi_rx_free_indir_table(efx);
2293         if (rss_spread > 1) {
2294                 efx_set_default_rx_indir_table(efx, &efx->rss_context);
2295                 rc = efx->type->rx_push_rss_config(efx, false,
2296                                    efx->rss_context.rx_indir_table, NULL);
2297         }
2298         return rc;
2299 }