New upstream version 18.02
[deb_dpdk.git] / drivers / net / sfc / sfc_filter.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright (c) 2017-2018 Solarflare Communications Inc.
4  * All rights reserved.
5  *
6  * This software was jointly developed between OKTET Labs (under contract
7  * for Solarflare) and Solarflare Communications, Inc.
8  */
9
10 #include <rte_common.h>
11
12 #include "efx.h"
13
14 #include "sfc.h"
15 #include "sfc_log.h"
16
17 boolean_t
18 sfc_filter_is_match_supported(struct sfc_adapter *sa, uint32_t match)
19 {
20         struct sfc_filter *filter = &sa->filter;
21         size_t i;
22
23         for (i = 0; i < filter->supported_match_num; ++i) {
24                 if (match == filter->supported_match[i])
25                         return B_TRUE;
26         }
27
28         return B_FALSE;
29 }
30
31 static int
32 sfc_filter_cache_match_supported(struct sfc_adapter *sa)
33 {
34         struct sfc_filter *filter = &sa->filter;
35         size_t num = filter->supported_match_num;
36         uint32_t *buf = filter->supported_match;
37         unsigned int retry;
38         int rc;
39
40         /* Just a guess of possibly sufficient entries */
41         if (num == 0)
42                 num = 16;
43
44         for (retry = 0; retry < 2; ++retry) {
45                 if (num != filter->supported_match_num) {
46                         rc = ENOMEM;
47                         buf = rte_realloc(buf, num * sizeof(*buf), 0);
48                         if (buf == NULL)
49                                 goto fail_realloc;
50                 }
51
52                 rc = efx_filter_supported_filters(sa->nic, buf, num, &num);
53                 if (rc == 0) {
54                         filter->supported_match_num = num;
55                         filter->supported_match = buf;
56
57                         return 0;
58                 } else if (rc != ENOSPC) {
59                         goto fail_efx_filter_supported_filters;
60                 }
61         }
62
63         SFC_ASSERT(rc == ENOSPC);
64
65 fail_efx_filter_supported_filters:
66 fail_realloc:
67         /* Original pointer is not freed by rte_realloc() on failure */
68         rte_free(buf);
69         filter->supported_match = NULL;
70         filter->supported_match_num = 0;
71         return rc;
72 }
73
74 int
75 sfc_filter_attach(struct sfc_adapter *sa)
76 {
77         int rc;
78
79         sfc_log_init(sa, "entry");
80
81         rc = efx_filter_init(sa->nic);
82         if (rc != 0)
83                 goto fail_filter_init;
84
85         rc = sfc_filter_cache_match_supported(sa);
86         if (rc != 0)
87                 goto fail_cache_match_supported;
88
89         efx_filter_fini(sa->nic);
90
91         sfc_log_init(sa, "done");
92
93         return 0;
94
95 fail_cache_match_supported:
96         efx_filter_fini(sa->nic);
97
98 fail_filter_init:
99         sfc_log_init(sa, "failed %d", rc);
100         return rc;
101 }
102
103 void
104 sfc_filter_detach(struct sfc_adapter *sa)
105 {
106         struct sfc_filter *filter = &sa->filter;
107
108         sfc_log_init(sa, "entry");
109
110         rte_free(filter->supported_match);
111         filter->supported_match = NULL;
112         filter->supported_match_num = 0;
113
114         sfc_log_init(sa, "done");
115 }