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 "nfp_net_repr.h"
40 
41 struct bpf_prog;
42 struct net_device;
43 struct pci_dev;
44 struct sk_buff;
45 struct tc_to_netdev;
46 struct sk_buff;
47 struct nfp_app;
48 struct nfp_cpp;
49 struct nfp_pf;
50 struct nfp_repr;
51 struct nfp_net;
52 
53 enum nfp_app_id {
54 	NFP_APP_CORE_NIC	= 0x1,
55 	NFP_APP_BPF_NIC		= 0x2,
56 	NFP_APP_FLOWER_NIC	= 0x3,
57 };
58 
59 extern const struct nfp_app_type app_nic;
60 extern const struct nfp_app_type app_bpf;
61 extern const struct nfp_app_type app_flower;
62 
63 /**
64  * struct nfp_app_type - application definition
65  * @id:		application ID
66  * @name:	application name
67  * @ctrl_has_meta:  control messages have prepend of type:5/port:CTRL
68  *
69  * Callbacks
70  * @init:	perform basic app checks and init
71  * @clean:	clean app state
72  * @extra_cap:	extra capabilities string
73  * @vnic_init:	init vNICs (assign port types, etc.)
74  * @vnic_clean:	clean up app's vNIC state
75  * @repr_open:	representor netdev open callback
76  * @repr_stop:	representor netdev stop callback
77  * @start:	start application logic
78  * @stop:	stop application logic
79  * @ctrl_msg_rx:    control message handler
80  * @setup_tc:	setup TC ndo
81  * @tc_busy:	TC HW offload busy (rules loaded)
82  * @xdp_offload:    offload an XDP program
83  * @eswitch_mode_get:    get SR-IOV eswitch mode
84  * @sriov_enable: app-specific sriov initialisation
85  * @sriov_disable: app-specific sriov clean-up
86  * @repr_get:	get representor netdev
87  */
88 struct nfp_app_type {
89 	enum nfp_app_id id;
90 	const char *name;
91 
92 	bool ctrl_has_meta;
93 
94 	int (*init)(struct nfp_app *app);
95 	void (*clean)(struct nfp_app *app);
96 
97 	const char *(*extra_cap)(struct nfp_app *app, struct nfp_net *nn);
98 
99 	int (*vnic_init)(struct nfp_app *app, struct nfp_net *nn,
100 			 unsigned int id);
101 	void (*vnic_clean)(struct nfp_app *app, struct nfp_net *nn);
102 
103 	int (*repr_open)(struct nfp_app *app, struct nfp_repr *repr);
104 	int (*repr_stop)(struct nfp_app *app, struct nfp_repr *repr);
105 
106 	int (*start)(struct nfp_app *app);
107 	void (*stop)(struct nfp_app *app);
108 
109 	void (*ctrl_msg_rx)(struct nfp_app *app, struct sk_buff *skb);
110 
111 	int (*setup_tc)(struct nfp_app *app, struct net_device *netdev,
112 			u32 handle, __be16 proto, struct tc_to_netdev *tc);
113 	bool (*tc_busy)(struct nfp_app *app, struct nfp_net *nn);
114 	int (*xdp_offload)(struct nfp_app *app, struct nfp_net *nn,
115 			   struct bpf_prog *prog);
116 
117 	int (*sriov_enable)(struct nfp_app *app, int num_vfs);
118 	void (*sriov_disable)(struct nfp_app *app);
119 
120 	enum devlink_eswitch_mode (*eswitch_mode_get)(struct nfp_app *app);
121 	struct net_device *(*repr_get)(struct nfp_app *app, u32 id);
122 };
123 
124 /**
125  * struct nfp_app - NFP application container
126  * @pdev:	backpointer to PCI device
127  * @pf:		backpointer to NFP PF structure
128  * @cpp:	pointer to the CPP handle
129  * @ctrl:	pointer to ctrl vNIC struct
130  * @reprs:	array of pointers to representors
131  * @type:	pointer to const application ops and info
132  * @priv:	app-specific priv data
133  */
134 struct nfp_app {
135 	struct pci_dev *pdev;
136 	struct nfp_pf *pf;
137 	struct nfp_cpp *cpp;
138 
139 	struct nfp_net *ctrl;
140 	struct nfp_reprs __rcu *reprs[NFP_REPR_TYPE_MAX + 1];
141 
142 	const struct nfp_app_type *type;
143 	void *priv;
144 };
145 
146 bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb);
147 
148 static inline int nfp_app_init(struct nfp_app *app)
149 {
150 	if (!app->type->init)
151 		return 0;
152 	return app->type->init(app);
153 }
154 
155 static inline void nfp_app_clean(struct nfp_app *app)
156 {
157 	if (app->type->clean)
158 		app->type->clean(app);
159 }
160 
161 static inline int nfp_app_vnic_init(struct nfp_app *app, struct nfp_net *nn,
162 				    unsigned int id)
163 {
164 	return app->type->vnic_init(app, nn, id);
165 }
166 
167 static inline void nfp_app_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
168 {
169 	if (app->type->vnic_clean)
170 		app->type->vnic_clean(app, nn);
171 }
172 
173 static inline int nfp_app_repr_open(struct nfp_app *app, struct nfp_repr *repr)
174 {
175 	if (!app->type->repr_open)
176 		return -EINVAL;
177 	return app->type->repr_open(app, repr);
178 }
179 
180 static inline int nfp_app_repr_stop(struct nfp_app *app, struct nfp_repr *repr)
181 {
182 	if (!app->type->repr_stop)
183 		return -EINVAL;
184 	return app->type->repr_stop(app, repr);
185 }
186 
187 static inline int nfp_app_start(struct nfp_app *app, struct nfp_net *ctrl)
188 {
189 	app->ctrl = ctrl;
190 	if (!app->type->start)
191 		return 0;
192 	return app->type->start(app);
193 }
194 
195 static inline void nfp_app_stop(struct nfp_app *app)
196 {
197 	if (!app->type->stop)
198 		return;
199 	app->type->stop(app);
200 }
201 
202 static inline const char *nfp_app_name(struct nfp_app *app)
203 {
204 	if (!app)
205 		return "";
206 	return app->type->name;
207 }
208 
209 static inline bool nfp_app_needs_ctrl_vnic(struct nfp_app *app)
210 {
211 	return app && app->type->ctrl_msg_rx;
212 }
213 
214 static inline bool nfp_app_ctrl_has_meta(struct nfp_app *app)
215 {
216 	return app->type->ctrl_has_meta;
217 }
218 
219 static inline const char *nfp_app_extra_cap(struct nfp_app *app,
220 					    struct nfp_net *nn)
221 {
222 	if (!app || !app->type->extra_cap)
223 		return "";
224 	return app->type->extra_cap(app, nn);
225 }
226 
227 static inline bool nfp_app_has_tc(struct nfp_app *app)
228 {
229 	return app && app->type->setup_tc;
230 }
231 
232 static inline bool nfp_app_tc_busy(struct nfp_app *app, struct nfp_net *nn)
233 {
234 	if (!app || !app->type->tc_busy)
235 		return false;
236 	return app->type->tc_busy(app, nn);
237 }
238 
239 static inline int nfp_app_setup_tc(struct nfp_app *app,
240 				   struct net_device *netdev,
241 				   u32 handle, __be16 proto,
242 				   struct tc_to_netdev *tc)
243 {
244 	if (!app || !app->type->setup_tc)
245 		return -EOPNOTSUPP;
246 	return app->type->setup_tc(app, netdev, handle, proto, tc);
247 }
248 
249 static inline int nfp_app_xdp_offload(struct nfp_app *app, struct nfp_net *nn,
250 				      struct bpf_prog *prog)
251 {
252 	if (!app || !app->type->xdp_offload)
253 		return -EOPNOTSUPP;
254 	return app->type->xdp_offload(app, nn, prog);
255 }
256 
257 static inline bool nfp_app_ctrl_tx(struct nfp_app *app, struct sk_buff *skb)
258 {
259 	return nfp_ctrl_tx(app->ctrl, skb);
260 }
261 
262 static inline void nfp_app_ctrl_rx(struct nfp_app *app, struct sk_buff *skb)
263 {
264 	app->type->ctrl_msg_rx(app, skb);
265 }
266 
267 static inline int nfp_app_eswitch_mode_get(struct nfp_app *app, u16 *mode)
268 {
269 	if (!app->type->eswitch_mode_get)
270 		return -EOPNOTSUPP;
271 
272 	*mode = app->type->eswitch_mode_get(app);
273 
274 	return 0;
275 }
276 
277 static inline int nfp_app_sriov_enable(struct nfp_app *app, int num_vfs)
278 {
279 	if (!app || !app->type->sriov_enable)
280 		return -EOPNOTSUPP;
281 	return app->type->sriov_enable(app, num_vfs);
282 }
283 
284 static inline void nfp_app_sriov_disable(struct nfp_app *app)
285 {
286 	if (app && app->type->sriov_disable)
287 		app->type->sriov_disable(app);
288 }
289 
290 static inline struct net_device *nfp_app_repr_get(struct nfp_app *app, u32 id)
291 {
292 	if (unlikely(!app || !app->type->repr_get))
293 		return NULL;
294 
295 	return app->type->repr_get(app, id);
296 }
297 
298 struct nfp_reprs *
299 nfp_app_reprs_set(struct nfp_app *app, enum nfp_repr_type type,
300 		  struct nfp_reprs *reprs);
301 
302 const char *nfp_app_mip_name(struct nfp_app *app);
303 struct sk_buff *
304 nfp_app_ctrl_msg_alloc(struct nfp_app *app, unsigned int size, gfp_t priority);
305 
306 struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id);
307 void nfp_app_free(struct nfp_app *app);
308 
309 /* Callbacks shared between apps */
310 
311 int nfp_app_nic_vnic_init(struct nfp_app *app, struct nfp_net *nn,
312 			  unsigned int id);
313 
314 #endif
315