2 * Copyright (C) 2017 Netronome Systems, Inc.
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.
9 * The BSD 2-Clause License:
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
15 * 1. Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
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.
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
37 #include <net/devlink.h>
39 #include <trace/events/devlink.h>
41 #include "nfp_net_repr.h"
46 struct netlink_ext_ack;
57 NFP_APP_CORE_NIC = 0x1,
58 NFP_APP_BPF_NIC = 0x2,
59 NFP_APP_FLOWER_NIC = 0x3,
60 NFP_APP_ACTIVE_BUFFER_MGMT_NIC = 0x4,
63 extern const struct nfp_app_type app_nic;
64 extern const struct nfp_app_type app_bpf;
65 extern const struct nfp_app_type app_flower;
66 extern const struct nfp_app_type app_abm;
69 * struct nfp_app_type - application definition
71 * @name: application name
72 * @ctrl_cap_mask: ctrl vNIC capability mask, allows disabling features like
73 * IRQMOD which are on by default but counter-productive for
74 * control messages which are often latency-sensitive
75 * @ctrl_has_meta: control messages have prepend of type:5/port:CTRL
78 * @init: perform basic app checks and init
79 * @clean: clean app state
80 * @extra_cap: extra capabilities string
81 * @vnic_alloc: allocate vNICs (assign port types, etc.)
82 * @vnic_free: free up app's vNIC state
83 * @vnic_init: vNIC netdev was registered
84 * @vnic_clean: vNIC netdev about to be unregistered
85 * @repr_init: representor about to be registered
86 * @repr_preclean: representor about to unregistered, executed before app
87 * reference to the it is removed
88 * @repr_clean: representor about to be unregistered
89 * @repr_open: representor netdev open callback
90 * @repr_stop: representor netdev stop callback
91 * @check_mtu: MTU change request on a netdev (verify it is valid)
92 * @repr_change_mtu: MTU change request on repr (make and verify change)
93 * @start: start application logic
94 * @stop: stop application logic
95 * @ctrl_msg_rx: control message handler
96 * @setup_tc: setup TC ndo
97 * @bpf: BPF ndo offload-related calls
98 * @xdp_offload: offload an XDP program
99 * @eswitch_mode_get: get SR-IOV eswitch mode
100 * @eswitch_mode_set: set SR-IOV eswitch mode (under pf->lock)
101 * @sriov_enable: app-specific sriov initialisation
102 * @sriov_disable: app-specific sriov clean-up
103 * @repr_get: get representor netdev
105 struct nfp_app_type {
112 int (*init)(struct nfp_app *app);
113 void (*clean)(struct nfp_app *app);
115 const char *(*extra_cap)(struct nfp_app *app, struct nfp_net *nn);
117 int (*vnic_alloc)(struct nfp_app *app, struct nfp_net *nn,
119 void (*vnic_free)(struct nfp_app *app, struct nfp_net *nn);
120 int (*vnic_init)(struct nfp_app *app, struct nfp_net *nn);
121 void (*vnic_clean)(struct nfp_app *app, struct nfp_net *nn);
123 int (*repr_init)(struct nfp_app *app, struct net_device *netdev);
124 void (*repr_preclean)(struct nfp_app *app, struct net_device *netdev);
125 void (*repr_clean)(struct nfp_app *app, struct net_device *netdev);
127 int (*repr_open)(struct nfp_app *app, struct nfp_repr *repr);
128 int (*repr_stop)(struct nfp_app *app, struct nfp_repr *repr);
130 int (*check_mtu)(struct nfp_app *app, struct net_device *netdev,
132 int (*repr_change_mtu)(struct nfp_app *app, struct net_device *netdev,
135 int (*start)(struct nfp_app *app);
136 void (*stop)(struct nfp_app *app);
138 void (*ctrl_msg_rx)(struct nfp_app *app, struct sk_buff *skb);
140 int (*setup_tc)(struct nfp_app *app, struct net_device *netdev,
141 enum tc_setup_type type, void *type_data);
142 int (*bpf)(struct nfp_app *app, struct nfp_net *nn,
143 struct netdev_bpf *xdp);
144 int (*xdp_offload)(struct nfp_app *app, struct nfp_net *nn,
145 struct bpf_prog *prog,
146 struct netlink_ext_ack *extack);
148 int (*sriov_enable)(struct nfp_app *app, int num_vfs);
149 void (*sriov_disable)(struct nfp_app *app);
151 enum devlink_eswitch_mode (*eswitch_mode_get)(struct nfp_app *app);
152 int (*eswitch_mode_set)(struct nfp_app *app, u16 mode);
153 struct net_device *(*repr_get)(struct nfp_app *app, u32 id);
157 * struct nfp_app - NFP application container
158 * @pdev: backpointer to PCI device
159 * @pf: backpointer to NFP PF structure
160 * @cpp: pointer to the CPP handle
161 * @ctrl: pointer to ctrl vNIC struct
162 * @reprs: array of pointers to representors
163 * @type: pointer to const application ops and info
164 * @priv: app-specific priv data
167 struct pci_dev *pdev;
171 struct nfp_net *ctrl;
172 struct nfp_reprs __rcu *reprs[NFP_REPR_TYPE_MAX + 1];
174 const struct nfp_app_type *type;
178 bool __nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb);
179 bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb);
181 static inline int nfp_app_init(struct nfp_app *app)
183 if (!app->type->init)
185 return app->type->init(app);
188 static inline void nfp_app_clean(struct nfp_app *app)
190 if (app->type->clean)
191 app->type->clean(app);
194 static inline int nfp_app_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
197 return app->type->vnic_alloc(app, nn, id);
200 static inline void nfp_app_vnic_free(struct nfp_app *app, struct nfp_net *nn)
202 if (app->type->vnic_free)
203 app->type->vnic_free(app, nn);
206 static inline int nfp_app_vnic_init(struct nfp_app *app, struct nfp_net *nn)
208 if (!app->type->vnic_init)
210 return app->type->vnic_init(app, nn);
213 static inline void nfp_app_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
215 if (app->type->vnic_clean)
216 app->type->vnic_clean(app, nn);
219 static inline int nfp_app_repr_open(struct nfp_app *app, struct nfp_repr *repr)
221 if (!app->type->repr_open)
223 return app->type->repr_open(app, repr);
226 static inline int nfp_app_repr_stop(struct nfp_app *app, struct nfp_repr *repr)
228 if (!app->type->repr_stop)
230 return app->type->repr_stop(app, repr);
234 nfp_app_repr_init(struct nfp_app *app, struct net_device *netdev)
236 if (!app->type->repr_init)
238 return app->type->repr_init(app, netdev);
242 nfp_app_repr_preclean(struct nfp_app *app, struct net_device *netdev)
244 if (app->type->repr_preclean)
245 app->type->repr_preclean(app, netdev);
249 nfp_app_repr_clean(struct nfp_app *app, struct net_device *netdev)
251 if (app->type->repr_clean)
252 app->type->repr_clean(app, netdev);
256 nfp_app_check_mtu(struct nfp_app *app, struct net_device *netdev, int new_mtu)
258 if (!app || !app->type->check_mtu)
260 return app->type->check_mtu(app, netdev, new_mtu);
264 nfp_app_repr_change_mtu(struct nfp_app *app, struct net_device *netdev,
267 if (!app || !app->type->repr_change_mtu)
269 return app->type->repr_change_mtu(app, netdev, new_mtu);
272 static inline int nfp_app_start(struct nfp_app *app, struct nfp_net *ctrl)
275 if (!app->type->start)
277 return app->type->start(app);
280 static inline void nfp_app_stop(struct nfp_app *app)
282 if (!app->type->stop)
284 app->type->stop(app);
287 static inline const char *nfp_app_name(struct nfp_app *app)
291 return app->type->name;
294 static inline bool nfp_app_needs_ctrl_vnic(struct nfp_app *app)
296 return app && app->type->ctrl_msg_rx;
299 static inline bool nfp_app_ctrl_has_meta(struct nfp_app *app)
301 return app->type->ctrl_has_meta;
304 static inline const char *nfp_app_extra_cap(struct nfp_app *app,
307 if (!app || !app->type->extra_cap)
309 return app->type->extra_cap(app, nn);
312 static inline bool nfp_app_has_tc(struct nfp_app *app)
314 return app && app->type->setup_tc;
317 static inline int nfp_app_setup_tc(struct nfp_app *app,
318 struct net_device *netdev,
319 enum tc_setup_type type, void *type_data)
321 if (!app || !app->type->setup_tc)
323 return app->type->setup_tc(app, netdev, type, type_data);
326 static inline int nfp_app_bpf(struct nfp_app *app, struct nfp_net *nn,
327 struct netdev_bpf *bpf)
329 if (!app || !app->type->bpf)
331 return app->type->bpf(app, nn, bpf);
334 static inline int nfp_app_xdp_offload(struct nfp_app *app, struct nfp_net *nn,
335 struct bpf_prog *prog,
336 struct netlink_ext_ack *extack)
338 if (!app || !app->type->xdp_offload)
340 return app->type->xdp_offload(app, nn, prog, extack);
343 static inline bool __nfp_app_ctrl_tx(struct nfp_app *app, struct sk_buff *skb)
345 trace_devlink_hwmsg(priv_to_devlink(app->pf), false, 0,
346 skb->data, skb->len);
348 return __nfp_ctrl_tx(app->ctrl, skb);
351 static inline bool nfp_app_ctrl_tx(struct nfp_app *app, struct sk_buff *skb)
353 trace_devlink_hwmsg(priv_to_devlink(app->pf), false, 0,
354 skb->data, skb->len);
356 return nfp_ctrl_tx(app->ctrl, skb);
359 static inline void nfp_app_ctrl_rx(struct nfp_app *app, struct sk_buff *skb)
361 trace_devlink_hwmsg(priv_to_devlink(app->pf), true, 0,
362 skb->data, skb->len);
364 app->type->ctrl_msg_rx(app, skb);
367 static inline int nfp_app_eswitch_mode_get(struct nfp_app *app, u16 *mode)
369 if (!app->type->eswitch_mode_get)
372 *mode = app->type->eswitch_mode_get(app);
377 static inline int nfp_app_eswitch_mode_set(struct nfp_app *app, u16 mode)
379 if (!app->type->eswitch_mode_set)
381 return app->type->eswitch_mode_set(app, mode);
384 static inline int nfp_app_sriov_enable(struct nfp_app *app, int num_vfs)
386 if (!app || !app->type->sriov_enable)
388 return app->type->sriov_enable(app, num_vfs);
391 static inline void nfp_app_sriov_disable(struct nfp_app *app)
393 if (app && app->type->sriov_disable)
394 app->type->sriov_disable(app);
397 static inline struct net_device *nfp_app_repr_get(struct nfp_app *app, u32 id)
399 if (unlikely(!app || !app->type->repr_get))
402 return app->type->repr_get(app, id);
405 struct nfp_app *nfp_app_from_netdev(struct net_device *netdev);
408 nfp_reprs_get_locked(struct nfp_app *app, enum nfp_repr_type type);
410 nfp_app_reprs_set(struct nfp_app *app, enum nfp_repr_type type,
411 struct nfp_reprs *reprs);
413 const char *nfp_app_mip_name(struct nfp_app *app);
415 nfp_app_ctrl_msg_alloc(struct nfp_app *app, unsigned int size, gfp_t priority);
417 struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id);
418 void nfp_app_free(struct nfp_app *app);
420 /* Callbacks shared between apps */
422 int nfp_app_nic_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
424 int nfp_app_nic_vnic_init_phy_port(struct nfp_pf *pf, struct nfp_app *app,
425 struct nfp_net *nn, unsigned int id);