1 /*
2  * Copyright (C) 2017 Netronome Systems, Inc.
3  *
4  * This software is dual licensed under the GNU General License Version 2,
5  * June 1991 as shown in the file COPYING in the top-level directory of this
6  * source tree or the BSD 2-Clause License provided below.  You have the
7  * option to license this software under the complete terms of either license.
8  *
9  * The BSD 2-Clause License:
10  *
11  *     Redistribution and use in source and binary forms, with or
12  *     without modification, are permitted provided that the following
13  *     conditions are met:
14  *
15  *      1. Redistributions of source code must retain the above
16  *         copyright notice, this list of conditions and the following
17  *         disclaimer.
18  *
19  *      2. Redistributions in binary form must reproduce the above
20  *         copyright notice, this list of conditions and the following
21  *         disclaimer in the documentation and/or other materials
22  *         provided with the distribution.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31  * SOFTWARE.
32  */
33 
34 #ifndef _NFP_APP_H
35 #define _NFP_APP_H 1
36 
37 #include <net/devlink.h>
38 
39 #include <trace/events/devlink.h>
40 
41 #include "nfp_net_repr.h"
42 
43 struct bpf_prog;
44 struct net_device;
45 struct netdev_bpf;
46 struct pci_dev;
47 struct sk_buff;
48 struct sk_buff;
49 struct nfp_app;
50 struct nfp_cpp;
51 struct nfp_pf;
52 struct nfp_repr;
53 struct nfp_net;
54 
55 enum nfp_app_id {
56 	NFP_APP_CORE_NIC	= 0x1,
57 	NFP_APP_BPF_NIC		= 0x2,
58 	NFP_APP_FLOWER_NIC	= 0x3,
59 };
60 
61 extern const struct nfp_app_type app_nic;
62 extern const struct nfp_app_type app_bpf;
63 extern const struct nfp_app_type app_flower;
64 
65 /**
66  * struct nfp_app_type - application definition
67  * @id:		application ID
68  * @name:	application name
69  * @ctrl_has_meta:  control messages have prepend of type:5/port:CTRL
70  *
71  * Callbacks
72  * @init:	perform basic app checks and init
73  * @clean:	clean app state
74  * @extra_cap:	extra capabilities string
75  * @vnic_alloc:	allocate vNICs (assign port types, etc.)
76  * @vnic_free:	free up app's vNIC state
77  * @vnic_init:	vNIC netdev was registered
78  * @vnic_clean:	vNIC netdev about to be unregistered
79  * @repr_init:	representor about to be registered
80  * @repr_clean:	representor about to be unregistered
81  * @repr_open:	representor netdev open callback
82  * @repr_stop:	representor netdev stop callback
83  * @start:	start application logic
84  * @stop:	stop application logic
85  * @ctrl_msg_rx:    control message handler
86  * @setup_tc:	setup TC ndo
87  * @tc_busy:	TC HW offload busy (rules loaded)
88  * @xdp_offload:    offload an XDP program
89  * @bpf_verifier_prep:	verifier prep for dev-specific BPF programs
90  * @bpf_translate:	translate call for dev-specific BPF programs
91  * @bpf_destroy:	destroy for dev-specific BPF programs
92  * @eswitch_mode_get:    get SR-IOV eswitch mode
93  * @sriov_enable: app-specific sriov initialisation
94  * @sriov_disable: app-specific sriov clean-up
95  * @repr_get:	get representor netdev
96  */
97 struct nfp_app_type {
98 	enum nfp_app_id id;
99 	const char *name;
100 
101 	bool ctrl_has_meta;
102 
103 	int (*init)(struct nfp_app *app);
104 	void (*clean)(struct nfp_app *app);
105 
106 	const char *(*extra_cap)(struct nfp_app *app, struct nfp_net *nn);
107 
108 	int (*vnic_alloc)(struct nfp_app *app, struct nfp_net *nn,
109 			  unsigned int id);
110 	void (*vnic_free)(struct nfp_app *app, struct nfp_net *nn);
111 	int (*vnic_init)(struct nfp_app *app, struct nfp_net *nn);
112 	void (*vnic_clean)(struct nfp_app *app, struct nfp_net *nn);
113 
114 	int (*repr_init)(struct nfp_app *app, struct net_device *netdev);
115 	void (*repr_clean)(struct nfp_app *app, struct net_device *netdev);
116 
117 	int (*repr_open)(struct nfp_app *app, struct nfp_repr *repr);
118 	int (*repr_stop)(struct nfp_app *app, struct nfp_repr *repr);
119 
120 	int (*start)(struct nfp_app *app);
121 	void (*stop)(struct nfp_app *app);
122 
123 	void (*ctrl_msg_rx)(struct nfp_app *app, struct sk_buff *skb);
124 
125 	int (*setup_tc)(struct nfp_app *app, struct net_device *netdev,
126 			enum tc_setup_type type, void *type_data);
127 	bool (*tc_busy)(struct nfp_app *app, struct nfp_net *nn);
128 	int (*xdp_offload)(struct nfp_app *app, struct nfp_net *nn,
129 			   struct bpf_prog *prog);
130 	int (*bpf_verifier_prep)(struct nfp_app *app, struct nfp_net *nn,
131 				 struct netdev_bpf *bpf);
132 	int (*bpf_translate)(struct nfp_app *app, struct nfp_net *nn,
133 			     struct bpf_prog *prog);
134 	int (*bpf_destroy)(struct nfp_app *app, struct nfp_net *nn,
135 			   struct bpf_prog *prog);
136 
137 	int (*sriov_enable)(struct nfp_app *app, int num_vfs);
138 	void (*sriov_disable)(struct nfp_app *app);
139 
140 	enum devlink_eswitch_mode (*eswitch_mode_get)(struct nfp_app *app);
141 	struct net_device *(*repr_get)(struct nfp_app *app, u32 id);
142 };
143 
144 /**
145  * struct nfp_app - NFP application container
146  * @pdev:	backpointer to PCI device
147  * @pf:		backpointer to NFP PF structure
148  * @cpp:	pointer to the CPP handle
149  * @ctrl:	pointer to ctrl vNIC struct
150  * @reprs:	array of pointers to representors
151  * @type:	pointer to const application ops and info
152  * @priv:	app-specific priv data
153  */
154 struct nfp_app {
155 	struct pci_dev *pdev;
156 	struct nfp_pf *pf;
157 	struct nfp_cpp *cpp;
158 
159 	struct nfp_net *ctrl;
160 	struct nfp_reprs __rcu *reprs[NFP_REPR_TYPE_MAX + 1];
161 
162 	const struct nfp_app_type *type;
163 	void *priv;
164 };
165 
166 bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb);
167 
168 static inline int nfp_app_init(struct nfp_app *app)
169 {
170 	if (!app->type->init)
171 		return 0;
172 	return app->type->init(app);
173 }
174 
175 static inline void nfp_app_clean(struct nfp_app *app)
176 {
177 	if (app->type->clean)
178 		app->type->clean(app);
179 }
180 
181 static inline int nfp_app_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
182 				     unsigned int id)
183 {
184 	return app->type->vnic_alloc(app, nn, id);
185 }
186 
187 static inline void nfp_app_vnic_free(struct nfp_app *app, struct nfp_net *nn)
188 {
189 	if (app->type->vnic_free)
190 		app->type->vnic_free(app, nn);
191 }
192 
193 static inline int nfp_app_vnic_init(struct nfp_app *app, struct nfp_net *nn)
194 {
195 	if (!app->type->vnic_init)
196 		return 0;
197 	return app->type->vnic_init(app, nn);
198 }
199 
200 static inline void nfp_app_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
201 {
202 	if (app->type->vnic_clean)
203 		app->type->vnic_clean(app, nn);
204 }
205 
206 static inline int nfp_app_repr_open(struct nfp_app *app, struct nfp_repr *repr)
207 {
208 	if (!app->type->repr_open)
209 		return -EINVAL;
210 	return app->type->repr_open(app, repr);
211 }
212 
213 static inline int nfp_app_repr_stop(struct nfp_app *app, struct nfp_repr *repr)
214 {
215 	if (!app->type->repr_stop)
216 		return -EINVAL;
217 	return app->type->repr_stop(app, repr);
218 }
219 
220 static inline int
221 nfp_app_repr_init(struct nfp_app *app, struct net_device *netdev)
222 {
223 	if (!app->type->repr_init)
224 		return 0;
225 	return app->type->repr_init(app, netdev);
226 }
227 
228 static inline void
229 nfp_app_repr_clean(struct nfp_app *app, struct net_device *netdev)
230 {
231 	if (app->type->repr_clean)
232 		app->type->repr_clean(app, netdev);
233 }
234 
235 static inline int nfp_app_start(struct nfp_app *app, struct nfp_net *ctrl)
236 {
237 	app->ctrl = ctrl;
238 	if (!app->type->start)
239 		return 0;
240 	return app->type->start(app);
241 }
242 
243 static inline void nfp_app_stop(struct nfp_app *app)
244 {
245 	if (!app->type->stop)
246 		return;
247 	app->type->stop(app);
248 }
249 
250 static inline const char *nfp_app_name(struct nfp_app *app)
251 {
252 	if (!app)
253 		return "";
254 	return app->type->name;
255 }
256 
257 static inline bool nfp_app_needs_ctrl_vnic(struct nfp_app *app)
258 {
259 	return app && app->type->ctrl_msg_rx;
260 }
261 
262 static inline bool nfp_app_ctrl_has_meta(struct nfp_app *app)
263 {
264 	return app->type->ctrl_has_meta;
265 }
266 
267 static inline const char *nfp_app_extra_cap(struct nfp_app *app,
268 					    struct nfp_net *nn)
269 {
270 	if (!app || !app->type->extra_cap)
271 		return "";
272 	return app->type->extra_cap(app, nn);
273 }
274 
275 static inline bool nfp_app_has_tc(struct nfp_app *app)
276 {
277 	return app && app->type->setup_tc;
278 }
279 
280 static inline bool nfp_app_tc_busy(struct nfp_app *app, struct nfp_net *nn)
281 {
282 	if (!app || !app->type->tc_busy)
283 		return false;
284 	return app->type->tc_busy(app, nn);
285 }
286 
287 static inline int nfp_app_setup_tc(struct nfp_app *app,
288 				   struct net_device *netdev,
289 				   enum tc_setup_type type, void *type_data)
290 {
291 	if (!app || !app->type->setup_tc)
292 		return -EOPNOTSUPP;
293 	return app->type->setup_tc(app, netdev, type, type_data);
294 }
295 
296 static inline int nfp_app_xdp_offload(struct nfp_app *app, struct nfp_net *nn,
297 				      struct bpf_prog *prog)
298 {
299 	if (!app || !app->type->xdp_offload)
300 		return -EOPNOTSUPP;
301 	return app->type->xdp_offload(app, nn, prog);
302 }
303 
304 static inline int
305 nfp_app_bpf_verifier_prep(struct nfp_app *app, struct nfp_net *nn,
306 			  struct netdev_bpf *bpf)
307 {
308 	if (!app || !app->type->bpf_verifier_prep)
309 		return -EOPNOTSUPP;
310 	return app->type->bpf_verifier_prep(app, nn, bpf);
311 }
312 
313 static inline int
314 nfp_app_bpf_translate(struct nfp_app *app, struct nfp_net *nn,
315 		      struct bpf_prog *prog)
316 {
317 	if (!app || !app->type->bpf_translate)
318 		return -EOPNOTSUPP;
319 	return app->type->bpf_translate(app, nn, prog);
320 }
321 
322 static inline int
323 nfp_app_bpf_destroy(struct nfp_app *app, struct nfp_net *nn,
324 		    struct bpf_prog *prog)
325 {
326 	if (!app || !app->type->bpf_destroy)
327 		return -EOPNOTSUPP;
328 	return app->type->bpf_destroy(app, nn, prog);
329 }
330 
331 static inline bool nfp_app_ctrl_tx(struct nfp_app *app, struct sk_buff *skb)
332 {
333 	trace_devlink_hwmsg(priv_to_devlink(app->pf), false, 0,
334 			    skb->data, skb->len);
335 
336 	return nfp_ctrl_tx(app->ctrl, skb);
337 }
338 
339 static inline void nfp_app_ctrl_rx(struct nfp_app *app, struct sk_buff *skb)
340 {
341 	trace_devlink_hwmsg(priv_to_devlink(app->pf), true, 0,
342 			    skb->data, skb->len);
343 
344 	app->type->ctrl_msg_rx(app, skb);
345 }
346 
347 static inline int nfp_app_eswitch_mode_get(struct nfp_app *app, u16 *mode)
348 {
349 	if (!app->type->eswitch_mode_get)
350 		return -EOPNOTSUPP;
351 
352 	*mode = app->type->eswitch_mode_get(app);
353 
354 	return 0;
355 }
356 
357 static inline int nfp_app_sriov_enable(struct nfp_app *app, int num_vfs)
358 {
359 	if (!app || !app->type->sriov_enable)
360 		return -EOPNOTSUPP;
361 	return app->type->sriov_enable(app, num_vfs);
362 }
363 
364 static inline void nfp_app_sriov_disable(struct nfp_app *app)
365 {
366 	if (app && app->type->sriov_disable)
367 		app->type->sriov_disable(app);
368 }
369 
370 static inline struct net_device *nfp_app_repr_get(struct nfp_app *app, u32 id)
371 {
372 	if (unlikely(!app || !app->type->repr_get))
373 		return NULL;
374 
375 	return app->type->repr_get(app, id);
376 }
377 
378 struct nfp_app *nfp_app_from_netdev(struct net_device *netdev);
379 
380 struct nfp_reprs *
381 nfp_app_reprs_set(struct nfp_app *app, enum nfp_repr_type type,
382 		  struct nfp_reprs *reprs);
383 
384 const char *nfp_app_mip_name(struct nfp_app *app);
385 struct sk_buff *
386 nfp_app_ctrl_msg_alloc(struct nfp_app *app, unsigned int size, gfp_t priority);
387 
388 struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id);
389 void nfp_app_free(struct nfp_app *app);
390 
391 /* Callbacks shared between apps */
392 
393 int nfp_app_nic_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
394 			   unsigned int id);
395 
396 #endif
397