]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/drivers/net/sfc/sfc_filter.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / dpdk / drivers / net / sfc / sfc_filter.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2 *
3 * Copyright(c) 2019-2020 Xilinx, Inc.
4 * Copyright(c) 2017-2019 Solarflare Communications Inc.
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 unsigned int i;
79
80 sfc_log_init(sa, "entry");
81
82 rc = efx_filter_init(sa->nic);
83 if (rc != 0)
84 goto fail_filter_init;
85
86 rc = sfc_filter_cache_match_supported(sa);
87 if (rc != 0)
88 goto fail_cache_match_supported;
89
90 efx_filter_fini(sa->nic);
91
92 sa->filter.supports_ip_proto_or_addr_filter = B_FALSE;
93 sa->filter.supports_rem_or_local_port_filter = B_FALSE;
94 for (i = 0; i < sa->filter.supported_match_num; ++i) {
95 if (sa->filter.supported_match[i] &
96 (EFX_FILTER_MATCH_IP_PROTO | EFX_FILTER_MATCH_LOC_HOST |
97 EFX_FILTER_MATCH_REM_HOST))
98 sa->filter.supports_ip_proto_or_addr_filter = B_TRUE;
99
100 if (sa->filter.supported_match[i] &
101 (EFX_FILTER_MATCH_LOC_PORT | EFX_FILTER_MATCH_REM_PORT))
102 sa->filter.supports_rem_or_local_port_filter = B_TRUE;
103 }
104
105 sfc_log_init(sa, "done");
106
107 return 0;
108
109 fail_cache_match_supported:
110 efx_filter_fini(sa->nic);
111
112 fail_filter_init:
113 sfc_log_init(sa, "failed %d", rc);
114 return rc;
115 }
116
117 void
118 sfc_filter_detach(struct sfc_adapter *sa)
119 {
120 struct sfc_filter *filter = &sa->filter;
121
122 sfc_log_init(sa, "entry");
123
124 rte_free(filter->supported_match);
125 filter->supported_match = NULL;
126 filter->supported_match_num = 0;
127
128 sfc_log_init(sa, "done");
129 }