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