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 sk_buff; 22 struct nfp_app; 23 struct nfp_cpp; 24 struct nfp_pf; 25 struct nfp_repr; 26 struct nfp_net; 27 28 enum 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 35 extern const struct nfp_app_type app_nic; 36 extern const struct nfp_app_type app_bpf; 37 extern const struct nfp_app_type app_flower; 38 extern 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 */ 84 struct 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 */ 162 struct 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 178 void nfp_check_rhashtable_empty(void *ptr, void *arg); 179 bool __nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb); 180 bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb); 181 182 static 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 189 static inline void nfp_app_clean(struct nfp_app *app) 190 { 191 if (app->type->clean) 192 app->type->clean(app); 193 } 194 195 int nfp_app_ndo_init(struct net_device *netdev); 196 void nfp_app_ndo_uninit(struct net_device *netdev); 197 198 static 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 204 static 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 210 static 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 217 static 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 223 static 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 230 static 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 237 static inline int 238 nfp_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 245 static inline void 246 nfp_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 252 static inline void 253 nfp_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 259 static inline int 260 nfp_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 267 static inline int 268 nfp_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 276 static inline const char *nfp_app_name(struct nfp_app *app) 277 { 278 if (!app) 279 return ""; 280 return app->type->name; 281 } 282 283 static inline bool nfp_app_needs_ctrl_vnic(struct nfp_app *app) 284 { 285 return app && app->type->ctrl_msg_rx; 286 } 287 288 static inline bool nfp_app_ctrl_has_meta(struct nfp_app *app) 289 { 290 return app->type->ctrl_has_meta; 291 } 292 293 static inline bool nfp_app_ctrl_uses_data_vnics(struct nfp_app *app) 294 { 295 return app && app->type->ctrl_msg_rx_raw; 296 } 297 298 static 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 306 static inline bool nfp_app_has_tc(struct nfp_app *app) 307 { 308 return app && app->type->setup_tc; 309 } 310 311 static 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 320 static 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 328 static 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 337 static 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 345 static 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 353 static 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 361 static inline void 362 nfp_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 371 static 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 381 static 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 388 static 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 395 static 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 401 static inline 402 struct 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 411 struct nfp_app *nfp_app_from_netdev(struct net_device *netdev); 412 413 u64 *nfp_app_port_get_stats(struct nfp_port *port, u64 *data); 414 int nfp_app_port_get_stats_count(struct nfp_port *port); 415 u8 *nfp_app_port_get_stats_strings(struct nfp_port *port, u8 *data); 416 417 struct nfp_reprs * 418 nfp_reprs_get_locked(struct nfp_app *app, enum nfp_repr_type type); 419 struct nfp_reprs * 420 nfp_app_reprs_set(struct nfp_app *app, enum nfp_repr_type type, 421 struct nfp_reprs *reprs); 422 423 const char *nfp_app_mip_name(struct nfp_app *app); 424 struct sk_buff * 425 nfp_app_ctrl_msg_alloc(struct nfp_app *app, unsigned int size, gfp_t priority); 426 427 struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id); 428 void nfp_app_free(struct nfp_app *app); 429 int nfp_app_start(struct nfp_app *app, struct nfp_net *ctrl); 430 void nfp_app_stop(struct nfp_app *app); 431 432 /* Callbacks shared between apps */ 433 434 int nfp_app_nic_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, 435 unsigned int id); 436 int nfp_app_nic_vnic_init_phy_port(struct nfp_pf *pf, struct nfp_app *app, 437 struct nfp_net *nn, unsigned int id); 438 439 struct devlink_port *nfp_devlink_get_devlink_port(struct net_device *netdev); 440 441 #endif 442