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 <trace/events/devlink.h> 40 41 #include "nfp_net_repr.h" 42 43 struct bpf_prog; 44 struct net_device; 45 struct netdev_bpf; 46 struct pci_dev; 47 struct sk_buff; 48 struct sk_buff; 49 struct nfp_app; 50 struct nfp_cpp; 51 struct nfp_pf; 52 struct nfp_repr; 53 struct nfp_net; 54 55 enum nfp_app_id { 56 NFP_APP_CORE_NIC = 0x1, 57 NFP_APP_BPF_NIC = 0x2, 58 NFP_APP_FLOWER_NIC = 0x3, 59 }; 60 61 extern const struct nfp_app_type app_nic; 62 extern const struct nfp_app_type app_bpf; 63 extern const struct nfp_app_type app_flower; 64 65 /** 66 * struct nfp_app_type - application definition 67 * @id: application ID 68 * @name: application name 69 * @ctrl_has_meta: control messages have prepend of type:5/port:CTRL 70 * 71 * Callbacks 72 * @init: perform basic app checks and init 73 * @clean: clean app state 74 * @extra_cap: extra capabilities string 75 * @vnic_alloc: allocate vNICs (assign port types, etc.) 76 * @vnic_free: free up app's vNIC state 77 * @vnic_init: vNIC netdev was registered 78 * @vnic_clean: vNIC netdev about to be unregistered 79 * @repr_init: representor about to be registered 80 * @repr_clean: representor about to be unregistered 81 * @repr_open: representor netdev open callback 82 * @repr_stop: representor netdev stop callback 83 * @start: start application logic 84 * @stop: stop application logic 85 * @ctrl_msg_rx: control message handler 86 * @setup_tc: setup TC ndo 87 * @tc_busy: TC HW offload busy (rules loaded) 88 * @xdp_offload: offload an XDP program 89 * @bpf_verifier_prep: verifier prep for dev-specific BPF programs 90 * @bpf_translate: translate call for dev-specific BPF programs 91 * @bpf_destroy: destroy for dev-specific BPF programs 92 * @eswitch_mode_get: get SR-IOV eswitch mode 93 * @sriov_enable: app-specific sriov initialisation 94 * @sriov_disable: app-specific sriov clean-up 95 * @repr_get: get representor netdev 96 */ 97 struct nfp_app_type { 98 enum nfp_app_id id; 99 const char *name; 100 101 bool ctrl_has_meta; 102 103 int (*init)(struct nfp_app *app); 104 void (*clean)(struct nfp_app *app); 105 106 const char *(*extra_cap)(struct nfp_app *app, struct nfp_net *nn); 107 108 int (*vnic_alloc)(struct nfp_app *app, struct nfp_net *nn, 109 unsigned int id); 110 void (*vnic_free)(struct nfp_app *app, struct nfp_net *nn); 111 int (*vnic_init)(struct nfp_app *app, struct nfp_net *nn); 112 void (*vnic_clean)(struct nfp_app *app, struct nfp_net *nn); 113 114 int (*repr_init)(struct nfp_app *app, struct net_device *netdev); 115 void (*repr_clean)(struct nfp_app *app, struct net_device *netdev); 116 117 int (*repr_open)(struct nfp_app *app, struct nfp_repr *repr); 118 int (*repr_stop)(struct nfp_app *app, struct nfp_repr *repr); 119 120 int (*start)(struct nfp_app *app); 121 void (*stop)(struct nfp_app *app); 122 123 void (*ctrl_msg_rx)(struct nfp_app *app, struct sk_buff *skb); 124 125 int (*setup_tc)(struct nfp_app *app, struct net_device *netdev, 126 enum tc_setup_type type, void *type_data); 127 bool (*tc_busy)(struct nfp_app *app, struct nfp_net *nn); 128 int (*xdp_offload)(struct nfp_app *app, struct nfp_net *nn, 129 struct bpf_prog *prog); 130 int (*bpf_verifier_prep)(struct nfp_app *app, struct nfp_net *nn, 131 struct netdev_bpf *bpf); 132 int (*bpf_translate)(struct nfp_app *app, struct nfp_net *nn, 133 struct bpf_prog *prog); 134 int (*bpf_destroy)(struct nfp_app *app, struct nfp_net *nn, 135 struct bpf_prog *prog); 136 137 int (*sriov_enable)(struct nfp_app *app, int num_vfs); 138 void (*sriov_disable)(struct nfp_app *app); 139 140 enum devlink_eswitch_mode (*eswitch_mode_get)(struct nfp_app *app); 141 struct net_device *(*repr_get)(struct nfp_app *app, u32 id); 142 }; 143 144 /** 145 * struct nfp_app - NFP application container 146 * @pdev: backpointer to PCI device 147 * @pf: backpointer to NFP PF structure 148 * @cpp: pointer to the CPP handle 149 * @ctrl: pointer to ctrl vNIC struct 150 * @reprs: array of pointers to representors 151 * @type: pointer to const application ops and info 152 * @priv: app-specific priv data 153 */ 154 struct nfp_app { 155 struct pci_dev *pdev; 156 struct nfp_pf *pf; 157 struct nfp_cpp *cpp; 158 159 struct nfp_net *ctrl; 160 struct nfp_reprs __rcu *reprs[NFP_REPR_TYPE_MAX + 1]; 161 162 const struct nfp_app_type *type; 163 void *priv; 164 }; 165 166 bool nfp_ctrl_tx(struct nfp_net *nn, struct sk_buff *skb); 167 168 static inline int nfp_app_init(struct nfp_app *app) 169 { 170 if (!app->type->init) 171 return 0; 172 return app->type->init(app); 173 } 174 175 static inline void nfp_app_clean(struct nfp_app *app) 176 { 177 if (app->type->clean) 178 app->type->clean(app); 179 } 180 181 static inline int nfp_app_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, 182 unsigned int id) 183 { 184 return app->type->vnic_alloc(app, nn, id); 185 } 186 187 static inline void nfp_app_vnic_free(struct nfp_app *app, struct nfp_net *nn) 188 { 189 if (app->type->vnic_free) 190 app->type->vnic_free(app, nn); 191 } 192 193 static inline int nfp_app_vnic_init(struct nfp_app *app, struct nfp_net *nn) 194 { 195 if (!app->type->vnic_init) 196 return 0; 197 return app->type->vnic_init(app, nn); 198 } 199 200 static inline void nfp_app_vnic_clean(struct nfp_app *app, struct nfp_net *nn) 201 { 202 if (app->type->vnic_clean) 203 app->type->vnic_clean(app, nn); 204 } 205 206 static inline int nfp_app_repr_open(struct nfp_app *app, struct nfp_repr *repr) 207 { 208 if (!app->type->repr_open) 209 return -EINVAL; 210 return app->type->repr_open(app, repr); 211 } 212 213 static inline int nfp_app_repr_stop(struct nfp_app *app, struct nfp_repr *repr) 214 { 215 if (!app->type->repr_stop) 216 return -EINVAL; 217 return app->type->repr_stop(app, repr); 218 } 219 220 static inline int 221 nfp_app_repr_init(struct nfp_app *app, struct net_device *netdev) 222 { 223 if (!app->type->repr_init) 224 return 0; 225 return app->type->repr_init(app, netdev); 226 } 227 228 static inline void 229 nfp_app_repr_clean(struct nfp_app *app, struct net_device *netdev) 230 { 231 if (app->type->repr_clean) 232 app->type->repr_clean(app, netdev); 233 } 234 235 static inline int nfp_app_start(struct nfp_app *app, struct nfp_net *ctrl) 236 { 237 app->ctrl = ctrl; 238 if (!app->type->start) 239 return 0; 240 return app->type->start(app); 241 } 242 243 static inline void nfp_app_stop(struct nfp_app *app) 244 { 245 if (!app->type->stop) 246 return; 247 app->type->stop(app); 248 } 249 250 static inline const char *nfp_app_name(struct nfp_app *app) 251 { 252 if (!app) 253 return ""; 254 return app->type->name; 255 } 256 257 static inline bool nfp_app_needs_ctrl_vnic(struct nfp_app *app) 258 { 259 return app && app->type->ctrl_msg_rx; 260 } 261 262 static inline bool nfp_app_ctrl_has_meta(struct nfp_app *app) 263 { 264 return app->type->ctrl_has_meta; 265 } 266 267 static inline const char *nfp_app_extra_cap(struct nfp_app *app, 268 struct nfp_net *nn) 269 { 270 if (!app || !app->type->extra_cap) 271 return ""; 272 return app->type->extra_cap(app, nn); 273 } 274 275 static inline bool nfp_app_has_tc(struct nfp_app *app) 276 { 277 return app && app->type->setup_tc; 278 } 279 280 static inline bool nfp_app_tc_busy(struct nfp_app *app, struct nfp_net *nn) 281 { 282 if (!app || !app->type->tc_busy) 283 return false; 284 return app->type->tc_busy(app, nn); 285 } 286 287 static inline int nfp_app_setup_tc(struct nfp_app *app, 288 struct net_device *netdev, 289 enum tc_setup_type type, void *type_data) 290 { 291 if (!app || !app->type->setup_tc) 292 return -EOPNOTSUPP; 293 return app->type->setup_tc(app, netdev, type, type_data); 294 } 295 296 static inline int nfp_app_xdp_offload(struct nfp_app *app, struct nfp_net *nn, 297 struct bpf_prog *prog) 298 { 299 if (!app || !app->type->xdp_offload) 300 return -EOPNOTSUPP; 301 return app->type->xdp_offload(app, nn, prog); 302 } 303 304 static inline int 305 nfp_app_bpf_verifier_prep(struct nfp_app *app, struct nfp_net *nn, 306 struct netdev_bpf *bpf) 307 { 308 if (!app || !app->type->bpf_verifier_prep) 309 return -EOPNOTSUPP; 310 return app->type->bpf_verifier_prep(app, nn, bpf); 311 } 312 313 static inline int 314 nfp_app_bpf_translate(struct nfp_app *app, struct nfp_net *nn, 315 struct bpf_prog *prog) 316 { 317 if (!app || !app->type->bpf_translate) 318 return -EOPNOTSUPP; 319 return app->type->bpf_translate(app, nn, prog); 320 } 321 322 static inline int 323 nfp_app_bpf_destroy(struct nfp_app *app, struct nfp_net *nn, 324 struct bpf_prog *prog) 325 { 326 if (!app || !app->type->bpf_destroy) 327 return -EOPNOTSUPP; 328 return app->type->bpf_destroy(app, nn, prog); 329 } 330 331 static inline bool nfp_app_ctrl_tx(struct nfp_app *app, struct sk_buff *skb) 332 { 333 trace_devlink_hwmsg(priv_to_devlink(app->pf), false, 0, 334 skb->data, skb->len); 335 336 return nfp_ctrl_tx(app->ctrl, skb); 337 } 338 339 static inline void nfp_app_ctrl_rx(struct nfp_app *app, struct sk_buff *skb) 340 { 341 trace_devlink_hwmsg(priv_to_devlink(app->pf), true, 0, 342 skb->data, skb->len); 343 344 app->type->ctrl_msg_rx(app, skb); 345 } 346 347 static inline int nfp_app_eswitch_mode_get(struct nfp_app *app, u16 *mode) 348 { 349 if (!app->type->eswitch_mode_get) 350 return -EOPNOTSUPP; 351 352 *mode = app->type->eswitch_mode_get(app); 353 354 return 0; 355 } 356 357 static inline int nfp_app_sriov_enable(struct nfp_app *app, int num_vfs) 358 { 359 if (!app || !app->type->sriov_enable) 360 return -EOPNOTSUPP; 361 return app->type->sriov_enable(app, num_vfs); 362 } 363 364 static inline void nfp_app_sriov_disable(struct nfp_app *app) 365 { 366 if (app && app->type->sriov_disable) 367 app->type->sriov_disable(app); 368 } 369 370 static inline struct net_device *nfp_app_repr_get(struct nfp_app *app, u32 id) 371 { 372 if (unlikely(!app || !app->type->repr_get)) 373 return NULL; 374 375 return app->type->repr_get(app, id); 376 } 377 378 struct nfp_app *nfp_app_from_netdev(struct net_device *netdev); 379 380 struct nfp_reprs * 381 nfp_app_reprs_set(struct nfp_app *app, enum nfp_repr_type type, 382 struct nfp_reprs *reprs); 383 384 const char *nfp_app_mip_name(struct nfp_app *app); 385 struct sk_buff * 386 nfp_app_ctrl_msg_alloc(struct nfp_app *app, unsigned int size, gfp_t priority); 387 388 struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id); 389 void nfp_app_free(struct nfp_app *app); 390 391 /* Callbacks shared between apps */ 392 393 int nfp_app_nic_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, 394 unsigned int id); 395 396 #endif 397