xref: /openbmc/linux/drivers/net/ethernet/netronome/nfp/nfp_app.h (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1  /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
2  /* Copyright (C) 2017-2018 Netronome Systems, Inc. */
3  
4  #ifndef _NFP_APP_H
5  #define _NFP_APP_H 1
6  
7  #include <net/devlink.h>
8  
9  #include <trace/events/devlink.h>
10  
11  #include "nfp_net_repr.h"
12  
13  #define NFP_APP_CTRL_MTU_MAX	U32_MAX
14  
15  struct bpf_prog;
16  struct net_device;
17  struct netdev_bpf;
18  struct netlink_ext_ack;
19  struct pci_dev;
20  struct sk_buff;
21  struct nfp_app;
22  struct nfp_cpp;
23  struct nfp_pf;
24  struct nfp_repr;
25  struct nfp_net;
26  
27  enum nfp_app_id {
28  	NFP_APP_CORE_NIC	= 0x1,
29  	NFP_APP_BPF_NIC		= 0x2,
30  	NFP_APP_FLOWER_NIC	= 0x3,
31  	NFP_APP_ACTIVE_BUFFER_MGMT_NIC = 0x4,
32  };
33  
34  extern const struct nfp_app_type app_nic;
35  extern const struct nfp_app_type app_bpf;
36  extern const struct nfp_app_type app_flower;
37  extern const struct nfp_app_type app_abm;
38  
39  /**
40   * struct nfp_app_type - application definition
41   * @id:		application ID
42   * @name:	application name
43   * @ctrl_cap_mask:  ctrl vNIC capability mask, allows disabling features like
44   *		    IRQMOD which are on by default but counter-productive for
45   *		    control messages which are often latency-sensitive
46   * @ctrl_has_meta:  control messages have prepend of type:5/port:CTRL
47   *
48   * Callbacks
49   * @init:	perform basic app checks and init
50   * @clean:	clean app state
51   * @extra_cap:	extra capabilities string
52   * @ndo_init:	vNIC and repr netdev .ndo_init
53   * @ndo_uninit:	vNIC and repr netdev .ndo_unint
54   * @vnic_alloc:	allocate vNICs (assign port types, etc.)
55   * @vnic_free:	free up app's vNIC state
56   * @vnic_init:	vNIC netdev was registered
57   * @vnic_clean:	vNIC netdev about to be unregistered
58   * @repr_init:	representor about to be registered
59   * @repr_preclean:	representor about to unregistered, executed before app
60   *			reference to the it is removed
61   * @repr_clean:	representor about to be unregistered
62   * @repr_open:	representor netdev open callback
63   * @repr_stop:	representor netdev stop callback
64   * @check_mtu:	MTU change request on a netdev (verify it is valid)
65   * @repr_change_mtu:	MTU change request on repr (make and verify change)
66   * @port_get_stats:		get extra ethtool statistics for a port
67   * @port_get_stats_count:	get count of extra statistics for a port
68   * @port_get_stats_strings:	get strings for extra statistics
69   * @start:	start application logic
70   * @stop:	stop application logic
71   * @netdev_event:	Netdevice notifier event
72   * @ctrl_msg_rx:    control message handler
73   * @ctrl_msg_rx_raw:	handler for control messages from data queues
74   * @setup_tc:	setup TC ndo
75   * @bpf:	BPF ndo offload-related calls
76   * @xdp_offload:    offload an XDP program
77   * @eswitch_mode_get:    get SR-IOV eswitch mode
78   * @eswitch_mode_set:    set SR-IOV eswitch mode
79   * @sriov_enable: app-specific sriov initialisation
80   * @sriov_disable: app-specific sriov clean-up
81   * @dev_get:	get representor or internal port representing netdev
82   */
83  struct nfp_app_type {
84  	enum nfp_app_id id;
85  	const char *name;
86  
87  	u32 ctrl_cap_mask;
88  	bool ctrl_has_meta;
89  
90  	int (*init)(struct nfp_app *app);
91  	void (*clean)(struct nfp_app *app);
92  
93  	const char *(*extra_cap)(struct nfp_app *app, struct nfp_net *nn);
94  
95  	int (*ndo_init)(struct nfp_app *app, struct net_device *netdev);
96  	void (*ndo_uninit)(struct nfp_app *app, struct net_device *netdev);
97  
98  	int (*vnic_alloc)(struct nfp_app *app, struct nfp_net *nn,
99  			  unsigned int id);
100  	void (*vnic_free)(struct nfp_app *app, struct nfp_net *nn);
101  	int (*vnic_init)(struct nfp_app *app, struct nfp_net *nn);
102  	void (*vnic_clean)(struct nfp_app *app, struct nfp_net *nn);
103  
104  	int (*repr_init)(struct nfp_app *app, struct net_device *netdev);
105  	void (*repr_preclean)(struct nfp_app *app, struct net_device *netdev);
106  	void (*repr_clean)(struct nfp_app *app, struct net_device *netdev);
107  
108  	int (*repr_open)(struct nfp_app *app, struct nfp_repr *repr);
109  	int (*repr_stop)(struct nfp_app *app, struct nfp_repr *repr);
110  
111  	int (*check_mtu)(struct nfp_app *app, struct net_device *netdev,
112  			 int new_mtu);
113  	int (*repr_change_mtu)(struct nfp_app *app, struct net_device *netdev,
114  			       int new_mtu);
115  
116  	u64 *(*port_get_stats)(struct nfp_app *app,
117  			       struct nfp_port *port, u64 *data);
118  	int (*port_get_stats_count)(struct nfp_app *app, struct nfp_port *port);
119  	u8 *(*port_get_stats_strings)(struct nfp_app *app,
120  				      struct nfp_port *port, u8 *data);
121  
122  	int (*start)(struct nfp_app *app);
123  	void (*stop)(struct nfp_app *app);
124  
125  	int (*netdev_event)(struct nfp_app *app, struct net_device *netdev,
126  			    unsigned long event, void *ptr);
127  
128  	void (*ctrl_msg_rx)(struct nfp_app *app, struct sk_buff *skb);
129  	void (*ctrl_msg_rx_raw)(struct nfp_app *app, const void *data,
130  				unsigned int len);
131  
132  	int (*setup_tc)(struct nfp_app *app, struct net_device *netdev,
133  			enum tc_setup_type type, void *type_data);
134  	int (*bpf)(struct nfp_app *app, struct nfp_net *nn,
135  		   struct netdev_bpf *xdp);
136  	int (*xdp_offload)(struct nfp_app *app, struct nfp_net *nn,
137  			   struct bpf_prog *prog,
138  			   struct netlink_ext_ack *extack);
139  
140  	int (*sriov_enable)(struct nfp_app *app, int num_vfs);
141  	void (*sriov_disable)(struct nfp_app *app);
142  
143  	enum devlink_eswitch_mode (*eswitch_mode_get)(struct nfp_app *app);
144  	int (*eswitch_mode_set)(struct nfp_app *app, u16 mode);
145  	struct net_device *(*dev_get)(struct nfp_app *app, u32 id,
146  				      bool *redir_egress);
147  };
148  
149  /**
150   * struct nfp_app - NFP application container
151   * @pdev:	backpointer to PCI device
152   * @pf:		backpointer to NFP PF structure
153   * @cpp:	pointer to the CPP handle
154   * @ctrl:	pointer to ctrl vNIC struct
155   * @reprs:	array of pointers to representors
156   * @type:	pointer to const application ops and info
157   * @ctrl_mtu:	MTU to set on the control vNIC (set in .init())
158   * @netdev_nb:	Netdevice notifier block
159   * @priv:	app-specific priv data
160   */
161  struct nfp_app {
162  	struct pci_dev *pdev;
163  	struct nfp_pf *pf;
164  	struct nfp_cpp *cpp;
165  
166  	struct nfp_net *ctrl;
167  	struct nfp_reprs __rcu *reprs[NFP_REPR_TYPE_MAX + 1];
168  
169  	const struct nfp_app_type *type;
170  	unsigned int ctrl_mtu;
171  
172  	struct notifier_block netdev_nb;
173  
174  	void *priv;
175  };
176  
assert_nfp_app_locked(struct nfp_app * app)177  static inline void assert_nfp_app_locked(struct nfp_app *app)
178  {
179  	devl_assert_locked(priv_to_devlink(app->pf));
180  }
181  
nfp_app_is_locked(struct nfp_app * app)182  static inline bool nfp_app_is_locked(struct nfp_app *app)
183  {
184  	return devl_lock_is_held(priv_to_devlink(app->pf));
185  }
186  
187  void nfp_check_rhashtable_empty(void *ptr, void *arg);
188  bool __nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb);
189  bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb);
190  
nfp_app_init(struct nfp_app * app)191  static inline int nfp_app_init(struct nfp_app *app)
192  {
193  	if (!app->type->init)
194  		return 0;
195  	return app->type->init(app);
196  }
197  
nfp_app_clean(struct nfp_app * app)198  static inline void nfp_app_clean(struct nfp_app *app)
199  {
200  	if (app->type->clean)
201  		app->type->clean(app);
202  }
203  
204  int nfp_app_ndo_init(struct net_device *netdev);
205  void nfp_app_ndo_uninit(struct net_device *netdev);
206  
nfp_app_vnic_alloc(struct nfp_app * app,struct nfp_net * nn,unsigned int id)207  static inline int nfp_app_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
208  				     unsigned int id)
209  {
210  	return app->type->vnic_alloc(app, nn, id);
211  }
212  
nfp_app_vnic_free(struct nfp_app * app,struct nfp_net * nn)213  static inline void nfp_app_vnic_free(struct nfp_app *app, struct nfp_net *nn)
214  {
215  	if (app->type->vnic_free)
216  		app->type->vnic_free(app, nn);
217  }
218  
nfp_app_vnic_init(struct nfp_app * app,struct nfp_net * nn)219  static inline int nfp_app_vnic_init(struct nfp_app *app, struct nfp_net *nn)
220  {
221  	if (!app->type->vnic_init)
222  		return 0;
223  	return app->type->vnic_init(app, nn);
224  }
225  
nfp_app_vnic_clean(struct nfp_app * app,struct nfp_net * nn)226  static inline void nfp_app_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
227  {
228  	if (app->type->vnic_clean)
229  		app->type->vnic_clean(app, nn);
230  }
231  
nfp_app_repr_open(struct nfp_app * app,struct nfp_repr * repr)232  static inline int nfp_app_repr_open(struct nfp_app *app, struct nfp_repr *repr)
233  {
234  	if (!app->type->repr_open)
235  		return -EINVAL;
236  	return app->type->repr_open(app, repr);
237  }
238  
nfp_app_repr_stop(struct nfp_app * app,struct nfp_repr * repr)239  static inline int nfp_app_repr_stop(struct nfp_app *app, struct nfp_repr *repr)
240  {
241  	if (!app->type->repr_stop)
242  		return -EINVAL;
243  	return app->type->repr_stop(app, repr);
244  }
245  
246  static inline int
nfp_app_repr_init(struct nfp_app * app,struct net_device * netdev)247  nfp_app_repr_init(struct nfp_app *app, struct net_device *netdev)
248  {
249  	if (!app->type->repr_init)
250  		return 0;
251  	return app->type->repr_init(app, netdev);
252  }
253  
254  static inline void
nfp_app_repr_preclean(struct nfp_app * app,struct net_device * netdev)255  nfp_app_repr_preclean(struct nfp_app *app, struct net_device *netdev)
256  {
257  	if (app->type->repr_preclean)
258  		app->type->repr_preclean(app, netdev);
259  }
260  
261  static inline void
nfp_app_repr_clean(struct nfp_app * app,struct net_device * netdev)262  nfp_app_repr_clean(struct nfp_app *app, struct net_device *netdev)
263  {
264  	if (app->type->repr_clean)
265  		app->type->repr_clean(app, netdev);
266  }
267  
268  static inline int
nfp_app_check_mtu(struct nfp_app * app,struct net_device * netdev,int new_mtu)269  nfp_app_check_mtu(struct nfp_app *app, struct net_device *netdev, int new_mtu)
270  {
271  	if (!app || !app->type->check_mtu)
272  		return 0;
273  	return app->type->check_mtu(app, netdev, new_mtu);
274  }
275  
276  static inline int
nfp_app_repr_change_mtu(struct nfp_app * app,struct net_device * netdev,int new_mtu)277  nfp_app_repr_change_mtu(struct nfp_app *app, struct net_device *netdev,
278  			int new_mtu)
279  {
280  	if (!app || !app->type->repr_change_mtu)
281  		return 0;
282  	return app->type->repr_change_mtu(app, netdev, new_mtu);
283  }
284  
nfp_app_name(struct nfp_app * app)285  static inline const char *nfp_app_name(struct nfp_app *app)
286  {
287  	if (!app)
288  		return "";
289  	return app->type->name;
290  }
291  
nfp_app_needs_ctrl_vnic(struct nfp_app * app)292  static inline bool nfp_app_needs_ctrl_vnic(struct nfp_app *app)
293  {
294  	return app && app->type->ctrl_msg_rx;
295  }
296  
nfp_app_ctrl_has_meta(struct nfp_app * app)297  static inline bool nfp_app_ctrl_has_meta(struct nfp_app *app)
298  {
299  	return app->type->ctrl_has_meta;
300  }
301  
nfp_app_ctrl_uses_data_vnics(struct nfp_app * app)302  static inline bool nfp_app_ctrl_uses_data_vnics(struct nfp_app *app)
303  {
304  	return app && app->type->ctrl_msg_rx_raw;
305  }
306  
nfp_app_extra_cap(struct nfp_app * app,struct nfp_net * nn)307  static inline const char *nfp_app_extra_cap(struct nfp_app *app,
308  					    struct nfp_net *nn)
309  {
310  	if (!app || !app->type->extra_cap)
311  		return "";
312  	return app->type->extra_cap(app, nn);
313  }
314  
nfp_app_has_tc(struct nfp_app * app)315  static inline bool nfp_app_has_tc(struct nfp_app *app)
316  {
317  	return app && app->type->setup_tc;
318  }
319  
nfp_app_setup_tc(struct nfp_app * app,struct net_device * netdev,enum tc_setup_type type,void * type_data)320  static inline int nfp_app_setup_tc(struct nfp_app *app,
321  				   struct net_device *netdev,
322  				   enum tc_setup_type type, void *type_data)
323  {
324  	if (!app || !app->type->setup_tc)
325  		return -EOPNOTSUPP;
326  	return app->type->setup_tc(app, netdev, type, type_data);
327  }
328  
nfp_app_bpf(struct nfp_app * app,struct nfp_net * nn,struct netdev_bpf * bpf)329  static inline int nfp_app_bpf(struct nfp_app *app, struct nfp_net *nn,
330  			      struct netdev_bpf *bpf)
331  {
332  	if (!app || !app->type->bpf)
333  		return -EINVAL;
334  	return app->type->bpf(app, nn, bpf);
335  }
336  
nfp_app_xdp_offload(struct nfp_app * app,struct nfp_net * nn,struct bpf_prog * prog,struct netlink_ext_ack * extack)337  static inline int nfp_app_xdp_offload(struct nfp_app *app, struct nfp_net *nn,
338  				      struct bpf_prog *prog,
339  				      struct netlink_ext_ack *extack)
340  {
341  	if (!app || !app->type->xdp_offload)
342  		return -EOPNOTSUPP;
343  	return app->type->xdp_offload(app, nn, prog, extack);
344  }
345  
__nfp_app_ctrl_tx(struct nfp_app * app,struct sk_buff * skb)346  static inline bool __nfp_app_ctrl_tx(struct nfp_app *app, struct sk_buff *skb)
347  {
348  	trace_devlink_hwmsg(priv_to_devlink(app->pf), false, 0,
349  			    skb->data, skb->len);
350  
351  	return __nfp_ctrl_tx(app->ctrl, skb);
352  }
353  
nfp_app_ctrl_tx(struct nfp_app * app,struct sk_buff * skb)354  static inline bool nfp_app_ctrl_tx(struct nfp_app *app, struct sk_buff *skb)
355  {
356  	trace_devlink_hwmsg(priv_to_devlink(app->pf), false, 0,
357  			    skb->data, skb->len);
358  
359  	return nfp_ctrl_tx(app->ctrl, skb);
360  }
361  
nfp_app_ctrl_rx(struct nfp_app * app,struct sk_buff * skb)362  static inline void nfp_app_ctrl_rx(struct nfp_app *app, struct sk_buff *skb)
363  {
364  	trace_devlink_hwmsg(priv_to_devlink(app->pf), true, 0,
365  			    skb->data, skb->len);
366  
367  	app->type->ctrl_msg_rx(app, skb);
368  }
369  
370  static inline void
nfp_app_ctrl_rx_raw(struct nfp_app * app,const void * data,unsigned int len)371  nfp_app_ctrl_rx_raw(struct nfp_app *app, const void *data, unsigned int len)
372  {
373  	if (!app || !app->type->ctrl_msg_rx_raw)
374  		return;
375  
376  	trace_devlink_hwmsg(priv_to_devlink(app->pf), true, 0, data, len);
377  	app->type->ctrl_msg_rx_raw(app, data, len);
378  }
379  
nfp_app_eswitch_mode_get(struct nfp_app * app,u16 * mode)380  static inline int nfp_app_eswitch_mode_get(struct nfp_app *app, u16 *mode)
381  {
382  	if (!app->type->eswitch_mode_get)
383  		return -EOPNOTSUPP;
384  
385  	*mode = app->type->eswitch_mode_get(app);
386  
387  	return 0;
388  }
389  
nfp_app_eswitch_mode_set(struct nfp_app * app,u16 mode)390  static inline int nfp_app_eswitch_mode_set(struct nfp_app *app, u16 mode)
391  {
392  	if (!app->type->eswitch_mode_set)
393  		return -EOPNOTSUPP;
394  	return app->type->eswitch_mode_set(app, mode);
395  }
396  
nfp_app_sriov_enable(struct nfp_app * app,int num_vfs)397  static inline int nfp_app_sriov_enable(struct nfp_app *app, int num_vfs)
398  {
399  	if (!app || !app->type->sriov_enable)
400  		return -EOPNOTSUPP;
401  	return app->type->sriov_enable(app, num_vfs);
402  }
403  
nfp_app_sriov_disable(struct nfp_app * app)404  static inline void nfp_app_sriov_disable(struct nfp_app *app)
405  {
406  	if (app && app->type->sriov_disable)
407  		app->type->sriov_disable(app);
408  }
409  
410  static inline
nfp_app_dev_get(struct nfp_app * app,u32 id,bool * redir_egress)411  struct net_device *nfp_app_dev_get(struct nfp_app *app, u32 id,
412  				   bool *redir_egress)
413  {
414  	if (unlikely(!app || !app->type->dev_get))
415  		return NULL;
416  
417  	return app->type->dev_get(app, id, redir_egress);
418  }
419  
420  struct nfp_app *nfp_app_from_netdev(struct net_device *netdev);
421  
422  u64 *nfp_app_port_get_stats(struct nfp_port *port, u64 *data);
423  int nfp_app_port_get_stats_count(struct nfp_port *port);
424  u8 *nfp_app_port_get_stats_strings(struct nfp_port *port, u8 *data);
425  
426  struct nfp_reprs *
427  nfp_reprs_get_locked(struct nfp_app *app, enum nfp_repr_type type);
428  struct nfp_reprs *
429  nfp_app_reprs_set(struct nfp_app *app, enum nfp_repr_type type,
430  		  struct nfp_reprs *reprs);
431  
432  const char *nfp_app_mip_name(struct nfp_app *app);
433  struct sk_buff *
434  nfp_app_ctrl_msg_alloc(struct nfp_app *app, unsigned int size, gfp_t priority);
435  
436  struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id);
437  void nfp_app_free(struct nfp_app *app);
438  int nfp_app_start(struct nfp_app *app, struct nfp_net *ctrl);
439  void nfp_app_stop(struct nfp_app *app);
440  
441  /* Callbacks shared between apps */
442  
443  int nfp_app_nic_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
444  			   unsigned int id);
445  int nfp_app_nic_vnic_init_phy_port(struct nfp_pf *pf, struct nfp_app *app,
446  				   struct nfp_net *nn, unsigned int id);
447  
448  #endif
449