net/sfc: add representors proxy infrastructure
[dpdk.git] / drivers / net / sfc / sfc_repr_proxy.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019-2021 Xilinx, Inc.
4  * Copyright(c) 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_service.h>
11 #include <rte_service_component.h>
12
13 #include "sfc_log.h"
14 #include "sfc_service.h"
15 #include "sfc_repr_proxy.h"
16 #include "sfc.h"
17
18 static int32_t
19 sfc_repr_proxy_routine(void *arg)
20 {
21         struct sfc_repr_proxy *rp = arg;
22
23         /* Representor proxy boilerplate will be here */
24         RTE_SET_USED(rp);
25
26         return 0;
27 }
28
29 int
30 sfc_repr_proxy_attach(struct sfc_adapter *sa)
31 {
32         struct sfc_repr_proxy *rp = &sa->repr_proxy;
33         struct rte_service_spec service;
34         uint32_t cid;
35         uint32_t sid;
36         int rc;
37
38         sfc_log_init(sa, "entry");
39
40         if (!sfc_repr_supported(sa)) {
41                 sfc_log_init(sa, "representors not supported - skip");
42                 return 0;
43         }
44
45         cid = sfc_get_service_lcore(sa->socket_id);
46         if (cid == RTE_MAX_LCORE && sa->socket_id != SOCKET_ID_ANY) {
47                 /* Warn and try to allocate on any NUMA node */
48                 sfc_warn(sa,
49                         "repr proxy: unable to get service lcore at socket %d",
50                         sa->socket_id);
51
52                 cid = sfc_get_service_lcore(SOCKET_ID_ANY);
53         }
54         if (cid == RTE_MAX_LCORE) {
55                 rc = ENOTSUP;
56                 sfc_err(sa, "repr proxy: failed to get service lcore");
57                 goto fail_get_service_lcore;
58         }
59
60         memset(&service, 0, sizeof(service));
61         snprintf(service.name, sizeof(service.name),
62                  "net_sfc_%hu_repr_proxy", sfc_sa2shared(sa)->port_id);
63         service.socket_id = rte_lcore_to_socket_id(cid);
64         service.callback = sfc_repr_proxy_routine;
65         service.callback_userdata = rp;
66
67         rc = rte_service_component_register(&service, &sid);
68         if (rc != 0) {
69                 rc = ENOEXEC;
70                 sfc_err(sa, "repr proxy: failed to register service component");
71                 goto fail_register;
72         }
73
74         rc = rte_service_map_lcore_set(sid, cid, 1);
75         if (rc != 0) {
76                 rc = -rc;
77                 sfc_err(sa, "repr proxy: failed to map lcore");
78                 goto fail_map_lcore;
79         }
80
81         rp->service_core_id = cid;
82         rp->service_id = sid;
83
84         sfc_log_init(sa, "done");
85
86         return 0;
87
88 fail_map_lcore:
89         rte_service_component_unregister(sid);
90
91 fail_register:
92         /*
93          * No need to rollback service lcore get since
94          * it just makes socket_id based search and remembers it.
95          */
96
97 fail_get_service_lcore:
98         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
99         return rc;
100 }
101
102 void
103 sfc_repr_proxy_detach(struct sfc_adapter *sa)
104 {
105         struct sfc_repr_proxy *rp = &sa->repr_proxy;
106
107         sfc_log_init(sa, "entry");
108
109         if (!sfc_repr_supported(sa)) {
110                 sfc_log_init(sa, "representors not supported - skip");
111                 return;
112         }
113
114         rte_service_map_lcore_set(rp->service_id, rp->service_core_id, 0);
115         rte_service_component_unregister(rp->service_id);
116
117         sfc_log_init(sa, "done");
118 }
119
120 int
121 sfc_repr_proxy_start(struct sfc_adapter *sa)
122 {
123         struct sfc_repr_proxy *rp = &sa->repr_proxy;
124         int rc;
125
126         sfc_log_init(sa, "entry");
127
128         /*
129          * The condition to start the proxy is insufficient. It will be
130          * complemented with representor port start/stop support.
131          */
132         if (!sfc_repr_supported(sa)) {
133                 sfc_log_init(sa, "representors not supported - skip");
134                 return 0;
135         }
136
137         /* Service core may be in "stopped" state, start it */
138         rc = rte_service_lcore_start(rp->service_core_id);
139         if (rc != 0 && rc != -EALREADY) {
140                 rc = -rc;
141                 sfc_err(sa, "failed to start service core for %s: %s",
142                         rte_service_get_name(rp->service_id),
143                         rte_strerror(rc));
144                 goto fail_start_core;
145         }
146
147         /* Run the service */
148         rc = rte_service_component_runstate_set(rp->service_id, 1);
149         if (rc < 0) {
150                 rc = -rc;
151                 sfc_err(sa, "failed to run %s component: %s",
152                         rte_service_get_name(rp->service_id),
153                         rte_strerror(rc));
154                 goto fail_component_runstate_set;
155         }
156         rc = rte_service_runstate_set(rp->service_id, 1);
157         if (rc < 0) {
158                 rc = -rc;
159                 sfc_err(sa, "failed to run %s: %s",
160                         rte_service_get_name(rp->service_id),
161                         rte_strerror(rc));
162                 goto fail_runstate_set;
163         }
164
165         sfc_log_init(sa, "done");
166
167         return 0;
168
169 fail_runstate_set:
170         rte_service_component_runstate_set(rp->service_id, 0);
171
172 fail_component_runstate_set:
173         /* Service lcore may be shared and we never stop it */
174
175 fail_start_core:
176         sfc_log_init(sa, "failed: %s", rte_strerror(rc));
177         return rc;
178 }
179
180 void
181 sfc_repr_proxy_stop(struct sfc_adapter *sa)
182 {
183         struct sfc_repr_proxy *rp = &sa->repr_proxy;
184         int rc;
185
186         sfc_log_init(sa, "entry");
187
188         if (!sfc_repr_supported(sa)) {
189                 sfc_log_init(sa, "representors not supported - skip");
190                 return;
191         }
192
193         rc = rte_service_runstate_set(rp->service_id, 0);
194         if (rc < 0) {
195                 sfc_err(sa, "failed to stop %s: %s",
196                         rte_service_get_name(rp->service_id),
197                         rte_strerror(-rc));
198         }
199
200         rc = rte_service_component_runstate_set(rp->service_id, 0);
201         if (rc < 0) {
202                 sfc_err(sa, "failed to stop %s component: %s",
203                         rte_service_get_name(rp->service_id),
204                         rte_strerror(-rc));
205         }
206
207         /* Service lcore may be shared and we never stop it */
208
209         sfc_log_init(sa, "done");
210 }