nfp: flower: increase cmesg reply timeout
[linux-block.git] / drivers / net / ethernet / netronome / nfp / flower / main.c
CommitLineData
96de2506
JK
1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
1025351a
SH
3
4#include <linux/etherdevice.h>
d2c2928d 5#include <linux/lockdep.h>
1025351a
SH
6#include <linux/pci.h>
7#include <linux/skbuff.h>
43f84b72 8#include <linux/vmalloc.h>
1025351a
SH
9#include <net/devlink.h>
10#include <net/dst_metadata.h>
11
8a276873 12#include "main.h"
1025351a 13#include "../nfpcore/nfp_cpp.h"
8a276873 14#include "../nfpcore/nfp_nffw.h"
1025351a
SH
15#include "../nfpcore/nfp_nsp.h"
16#include "../nfp_app.h"
17#include "../nfp_main.h"
18#include "../nfp_net.h"
19#include "../nfp_net_repr.h"
20#include "../nfp_port.h"
21#include "./cmsg.h"
22
8a276873
PJV
23#define NFP_FLOWER_ALLOWED_VER 0x0001000000010000UL
24
1025351a
SH
25static const char *nfp_flower_extra_cap(struct nfp_app *app, struct nfp_net *nn)
26{
27 return "FLOWER";
28}
29
30static enum devlink_eswitch_mode eswitch_mode_get(struct nfp_app *app)
31{
32 return DEVLINK_ESWITCH_MODE_SWITCHDEV;
33}
34
35static enum nfp_repr_type
36nfp_flower_repr_get_type_and_port(struct nfp_app *app, u32 port_id, u8 *port)
37{
38 switch (FIELD_GET(NFP_FLOWER_CMSG_PORT_TYPE, port_id)) {
39 case NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT:
40 *port = FIELD_GET(NFP_FLOWER_CMSG_PORT_PHYS_PORT_NUM,
41 port_id);
42 return NFP_REPR_TYPE_PHYS_PORT;
43
44 case NFP_FLOWER_CMSG_PORT_TYPE_PCIE_PORT:
45 *port = FIELD_GET(NFP_FLOWER_CMSG_PORT_VNIC, port_id);
46 if (FIELD_GET(NFP_FLOWER_CMSG_PORT_VNIC_TYPE, port_id) ==
47 NFP_FLOWER_CMSG_PORT_VNIC_TYPE_PF)
48 return NFP_REPR_TYPE_PF;
49 else
50 return NFP_REPR_TYPE_VF;
51 }
52
ee614c87 53 return __NFP_REPR_TYPE_MAX;
1025351a
SH
54}
55
56static struct net_device *
57nfp_flower_repr_get(struct nfp_app *app, u32 port_id)
58{
59 enum nfp_repr_type repr_type;
60 struct nfp_reprs *reprs;
61 u8 port = 0;
62
63 repr_type = nfp_flower_repr_get_type_and_port(app, port_id, &port);
ee614c87
JH
64 if (repr_type > NFP_REPR_TYPE_MAX)
65 return NULL;
1025351a
SH
66
67 reprs = rcu_dereference(app->reprs[repr_type]);
68 if (!reprs)
69 return NULL;
70
71 if (port >= reprs->num_reprs)
72 return NULL;
73
3eb47dfc 74 return rcu_dereference(reprs->reprs[port]);
1025351a
SH
75}
76
d2c2928d
DM
77static int
78nfp_flower_reprs_reify(struct nfp_app *app, enum nfp_repr_type type,
79 bool exists)
80{
81 struct nfp_reprs *reprs;
82 int i, err, count = 0;
83
84 reprs = rcu_dereference_protected(app->reprs[type],
85 lockdep_is_held(&app->pf->lock));
86 if (!reprs)
87 return 0;
88
3eb47dfc
JK
89 for (i = 0; i < reprs->num_reprs; i++) {
90 struct net_device *netdev;
91
92 netdev = nfp_repr_get_locked(app, reprs, i);
93 if (netdev) {
94 struct nfp_repr *repr = netdev_priv(netdev);
d2c2928d
DM
95
96 err = nfp_flower_cmsg_portreify(repr, exists);
97 if (err)
98 return err;
99 count++;
100 }
3eb47dfc 101 }
d2c2928d
DM
102
103 return count;
104}
105
106static int
107nfp_flower_wait_repr_reify(struct nfp_app *app, atomic_t *replies, int tot_repl)
108{
109 struct nfp_flower_priv *priv = app->priv;
d2c2928d
DM
110
111 if (!tot_repl)
112 return 0;
113
114 lockdep_assert_held(&app->pf->lock);
96439889
FL
115 if (!wait_event_timeout(priv->reify_wait_queue,
116 atomic_read(replies) >= tot_repl,
117 NFP_FL_REPLY_TIMEOUT)) {
d2c2928d
DM
118 nfp_warn(app->cpp, "Not all reprs responded to reify\n");
119 return -EIO;
120 }
121
122 return 0;
123}
124
5d7c64a7
JK
125static int
126nfp_flower_repr_netdev_open(struct nfp_app *app, struct nfp_repr *repr)
1025351a
SH
127{
128 int err;
129
29a5dcae 130 err = nfp_flower_cmsg_portmod(repr, true, repr->netdev->mtu, false);
1025351a
SH
131 if (err)
132 return err;
133
5d7c64a7 134 netif_tx_wake_all_queues(repr->netdev);
1025351a
SH
135
136 return 0;
137}
138
5d7c64a7
JK
139static int
140nfp_flower_repr_netdev_stop(struct nfp_app *app, struct nfp_repr *repr)
1025351a 141{
5d7c64a7 142 netif_tx_disable(repr->netdev);
1025351a 143
29a5dcae 144 return nfp_flower_cmsg_portmod(repr, false, repr->netdev->mtu, false);
1025351a
SH
145}
146
1a24d4f9
JH
147static void
148nfp_flower_repr_netdev_clean(struct nfp_app *app, struct net_device *netdev)
149{
b9452452
JH
150 struct nfp_repr *repr = netdev_priv(netdev);
151
152 kfree(repr->app_priv);
1a24d4f9
JH
153}
154
d2c2928d
DM
155static void
156nfp_flower_repr_netdev_preclean(struct nfp_app *app, struct net_device *netdev)
157{
158 struct nfp_repr *repr = netdev_priv(netdev);
159 struct nfp_flower_priv *priv = app->priv;
160 atomic_t *replies = &priv->reify_replies;
161 int err;
162
163 atomic_set(replies, 0);
164 err = nfp_flower_cmsg_portreify(repr, false);
165 if (err) {
166 nfp_warn(app->cpp, "Failed to notify firmware about repr destruction\n");
167 return;
168 }
169
170 nfp_flower_wait_repr_reify(app, replies, 1);
171}
172
24a021ed
SH
173static void nfp_flower_sriov_disable(struct nfp_app *app)
174{
192e6851
JK
175 struct nfp_flower_priv *priv = app->priv;
176
177 if (!priv->nn)
178 return;
179
24a021ed
SH
180 nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_VF);
181}
182
183static int
184nfp_flower_spawn_vnic_reprs(struct nfp_app *app,
185 enum nfp_flower_cmsg_port_vnic_type vnic_type,
186 enum nfp_repr_type repr_type, unsigned int cnt)
187{
188 u8 nfp_pcie = nfp_cppcore_pcie_unit(app->pf->cpp);
189 struct nfp_flower_priv *priv = app->priv;
d2c2928d 190 atomic_t *replies = &priv->reify_replies;
b9452452 191 struct nfp_flower_repr_priv *repr_priv;
38edbf6f 192 enum nfp_port_type port_type;
b9452452 193 struct nfp_repr *nfp_repr;
51ccc37d 194 struct nfp_reprs *reprs;
d2c2928d 195 int i, err, reify_cnt;
24a021ed 196 const u8 queue = 0;
24a021ed 197
38edbf6f
JK
198 port_type = repr_type == NFP_REPR_TYPE_PF ? NFP_PORT_PF_PORT :
199 NFP_PORT_VF_PORT;
200
24a021ed
SH
201 reprs = nfp_reprs_alloc(cnt);
202 if (!reprs)
203 return -ENOMEM;
204
205 for (i = 0; i < cnt; i++) {
3eb47dfc 206 struct net_device *repr;
38edbf6f 207 struct nfp_port *port;
24a021ed
SH
208 u32 port_id;
209
3eb47dfc
JK
210 repr = nfp_repr_alloc(app);
211 if (!repr) {
24a021ed
SH
212 err = -ENOMEM;
213 goto err_reprs_clean;
214 }
215
b9452452
JH
216 repr_priv = kzalloc(sizeof(*repr_priv), GFP_KERNEL);
217 if (!repr_priv) {
218 err = -ENOMEM;
219 goto err_reprs_clean;
220 }
221
222 nfp_repr = netdev_priv(repr);
223 nfp_repr->app_priv = repr_priv;
224
ef0ec676
JK
225 /* For now we only support 1 PF */
226 WARN_ON(repr_type == NFP_REPR_TYPE_PF && i);
227
3eb47dfc 228 port = nfp_port_alloc(app, port_type, repr);
3b734ff6
JP
229 if (IS_ERR(port)) {
230 err = PTR_ERR(port);
231 nfp_repr_free(repr);
232 goto err_reprs_clean;
233 }
38edbf6f
JK
234 if (repr_type == NFP_REPR_TYPE_PF) {
235 port->pf_id = i;
ef0ec676 236 port->vnic = priv->nn->dp.ctrl_bar;
38edbf6f 237 } else {
ef0ec676 238 port->pf_id = 0;
38edbf6f 239 port->vf_id = i;
ef0ec676
JK
240 port->vnic =
241 app->pf->vf_cfg_mem + i * NFP_NET_CFG_BAR_SZ;
38edbf6f
JK
242 }
243
3eb47dfc 244 eth_hw_addr_random(repr);
24a021ed
SH
245
246 port_id = nfp_flower_cmsg_pcie_port(nfp_pcie, vnic_type,
247 i, queue);
3eb47dfc 248 err = nfp_repr_init(app, repr,
38edbf6f
JK
249 port_id, port, priv->nn->dp.netdev);
250 if (err) {
251 nfp_port_free(port);
3b734ff6 252 nfp_repr_free(repr);
24a021ed 253 goto err_reprs_clean;
38edbf6f 254 }
24a021ed 255
3b734ff6 256 RCU_INIT_POINTER(reprs->reprs[i], repr);
24a021ed
SH
257 nfp_info(app->cpp, "%s%d Representor(%s) created\n",
258 repr_type == NFP_REPR_TYPE_PF ? "PF" : "VF", i,
3eb47dfc 259 repr->name);
24a021ed
SH
260 }
261
51ccc37d 262 nfp_app_reprs_set(app, repr_type, reprs);
24a021ed 263
d2c2928d
DM
264 atomic_set(replies, 0);
265 reify_cnt = nfp_flower_reprs_reify(app, repr_type, true);
266 if (reify_cnt < 0) {
267 err = reify_cnt;
268 nfp_warn(app->cpp, "Failed to notify firmware about repr creation\n");
269 goto err_reprs_remove;
270 }
271
272 err = nfp_flower_wait_repr_reify(app, replies, reify_cnt);
273 if (err)
274 goto err_reprs_remove;
275
24a021ed 276 return 0;
d2c2928d
DM
277err_reprs_remove:
278 reprs = nfp_app_reprs_set(app, repr_type, NULL);
24a021ed 279err_reprs_clean:
3eb47dfc 280 nfp_reprs_clean_and_free(app, reprs);
24a021ed
SH
281 return err;
282}
283
284static int nfp_flower_sriov_enable(struct nfp_app *app, int num_vfs)
285{
192e6851
JK
286 struct nfp_flower_priv *priv = app->priv;
287
288 if (!priv->nn)
289 return 0;
290
24a021ed
SH
291 return nfp_flower_spawn_vnic_reprs(app,
292 NFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF,
293 NFP_REPR_TYPE_VF, num_vfs);
294}
295
24a021ed
SH
296static int
297nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)
1025351a
SH
298{
299 struct nfp_eth_table *eth_tbl = app->pf->eth_tbl;
d2c2928d 300 atomic_t *replies = &priv->reify_replies;
b9452452
JH
301 struct nfp_flower_repr_priv *repr_priv;
302 struct nfp_repr *nfp_repr;
12acb133 303 struct sk_buff *ctrl_skb;
51ccc37d 304 struct nfp_reprs *reprs;
d2c2928d 305 int err, reify_cnt;
1025351a 306 unsigned int i;
1025351a 307
12acb133
SH
308 ctrl_skb = nfp_flower_cmsg_mac_repr_start(app, eth_tbl->count);
309 if (!ctrl_skb)
1025351a
SH
310 return -ENOMEM;
311
12acb133
SH
312 reprs = nfp_reprs_alloc(eth_tbl->max_index + 1);
313 if (!reprs) {
314 err = -ENOMEM;
315 goto err_free_ctrl_skb;
316 }
317
1025351a 318 for (i = 0; i < eth_tbl->count; i++) {
12acb133 319 unsigned int phys_port = eth_tbl->ports[i].index;
3eb47dfc 320 struct net_device *repr;
1025351a
SH
321 struct nfp_port *port;
322 u32 cmsg_port_id;
323
3eb47dfc
JK
324 repr = nfp_repr_alloc(app);
325 if (!repr) {
1025351a
SH
326 err = -ENOMEM;
327 goto err_reprs_clean;
328 }
329
b9452452
JH
330 repr_priv = kzalloc(sizeof(*repr_priv), GFP_KERNEL);
331 if (!repr_priv) {
332 err = -ENOMEM;
333 goto err_reprs_clean;
334 }
335
336 nfp_repr = netdev_priv(repr);
337 nfp_repr->app_priv = repr_priv;
338
3eb47dfc 339 port = nfp_port_alloc(app, NFP_PORT_PHYS_PORT, repr);
1025351a
SH
340 if (IS_ERR(port)) {
341 err = PTR_ERR(port);
3b734ff6 342 nfp_repr_free(repr);
1025351a
SH
343 goto err_reprs_clean;
344 }
345 err = nfp_port_init_phy_port(app->pf, app, port, i);
346 if (err) {
347 nfp_port_free(port);
3b734ff6 348 nfp_repr_free(repr);
1025351a
SH
349 goto err_reprs_clean;
350 }
351
3eb47dfc 352 SET_NETDEV_DEV(repr, &priv->nn->pdev->dev);
c55ca688 353 nfp_net_get_mac_addr(app->pf, repr, port);
1025351a
SH
354
355 cmsg_port_id = nfp_flower_cmsg_phys_port(phys_port);
3eb47dfc 356 err = nfp_repr_init(app, repr,
1025351a
SH
357 cmsg_port_id, port, priv->nn->dp.netdev);
358 if (err) {
359 nfp_port_free(port);
3b734ff6 360 nfp_repr_free(repr);
1025351a
SH
361 goto err_reprs_clean;
362 }
363
12acb133
SH
364 nfp_flower_cmsg_mac_repr_add(ctrl_skb, i,
365 eth_tbl->ports[i].nbi,
366 eth_tbl->ports[i].base,
367 phys_port);
368
3b734ff6 369 RCU_INIT_POINTER(reprs->reprs[phys_port], repr);
1025351a 370 nfp_info(app->cpp, "Phys Port %d Representor(%s) created\n",
3eb47dfc 371 phys_port, repr->name);
1025351a
SH
372 }
373
51ccc37d 374 nfp_app_reprs_set(app, NFP_REPR_TYPE_PHYS_PORT, reprs);
1025351a 375
d2c2928d 376 /* The REIFY/MAC_REPR control messages should be sent after the MAC
12acb133
SH
377 * representors are registered using nfp_app_reprs_set(). This is
378 * because the firmware may respond with control messages for the
379 * MAC representors, f.e. to provide the driver with information
380 * about their state, and without registration the driver will drop
381 * any such messages.
382 */
d2c2928d
DM
383 atomic_set(replies, 0);
384 reify_cnt = nfp_flower_reprs_reify(app, NFP_REPR_TYPE_PHYS_PORT, true);
385 if (reify_cnt < 0) {
386 err = reify_cnt;
387 nfp_warn(app->cpp, "Failed to notify firmware about repr creation\n");
388 goto err_reprs_remove;
389 }
390
391 err = nfp_flower_wait_repr_reify(app, replies, reify_cnt);
392 if (err)
393 goto err_reprs_remove;
394
12acb133
SH
395 nfp_ctrl_tx(app->ctrl, ctrl_skb);
396
1025351a 397 return 0;
d2c2928d
DM
398err_reprs_remove:
399 reprs = nfp_app_reprs_set(app, NFP_REPR_TYPE_PHYS_PORT, NULL);
1025351a 400err_reprs_clean:
3eb47dfc 401 nfp_reprs_clean_and_free(app, reprs);
12acb133
SH
402err_free_ctrl_skb:
403 kfree_skb(ctrl_skb);
1025351a
SH
404 return err;
405}
406
c496291c
JK
407static int nfp_flower_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
408 unsigned int id)
1025351a 409{
1025351a
SH
410 if (id > 0) {
411 nfp_warn(app->cpp, "FlowerNIC doesn't support more than one data vNIC\n");
412 goto err_invalid_port;
413 }
414
1025351a
SH
415 eth_hw_addr_random(nn->dp.netdev);
416 netif_keep_dst(nn->dp.netdev);
fe06a64e 417 nn->vnic_no_name = true;
1025351a
SH
418
419 return 0;
420
421err_invalid_port:
422 nn->port = nfp_port_alloc(app, NFP_PORT_INVALID, nn->dp.netdev);
423 return PTR_ERR_OR_ZERO(nn->port);
424}
425
c496291c
JK
426static void nfp_flower_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
427{
428 struct nfp_flower_priv *priv = app->priv;
429
192e6851
JK
430 if (app->pf->num_vfs)
431 nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_VF);
432 nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PF);
433 nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PHYS_PORT);
434
c496291c
JK
435 priv->nn = NULL;
436}
437
438static int nfp_flower_vnic_init(struct nfp_app *app, struct nfp_net *nn)
439{
440 struct nfp_flower_priv *priv = app->priv;
192e6851 441 int err;
c496291c
JK
442
443 priv->nn = nn;
444
192e6851
JK
445 err = nfp_flower_spawn_phy_reprs(app, app->priv);
446 if (err)
447 goto err_clear_nn;
448
449 err = nfp_flower_spawn_vnic_reprs(app,
450 NFP_FLOWER_CMSG_PORT_VNIC_TYPE_PF,
451 NFP_REPR_TYPE_PF, 1);
452 if (err)
453 goto err_destroy_reprs_phy;
454
455 if (app->pf->num_vfs) {
456 err = nfp_flower_spawn_vnic_reprs(app,
457 NFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF,
458 NFP_REPR_TYPE_VF,
459 app->pf->num_vfs);
460 if (err)
461 goto err_destroy_reprs_pf;
462 }
463
c496291c 464 return 0;
192e6851
JK
465
466err_destroy_reprs_pf:
467 nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PF);
468err_destroy_reprs_phy:
469 nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PHYS_PORT);
470err_clear_nn:
471 priv->nn = NULL;
472 return err;
c496291c
JK
473}
474
1025351a
SH
475static int nfp_flower_init(struct nfp_app *app)
476{
477 const struct nfp_pf *pf = app->pf;
12ecf615 478 u64 version, features, ctx_count;
b985f870 479 struct nfp_flower_priv *app_priv;
8a276873 480 int err;
1025351a
SH
481
482 if (!pf->eth_tbl) {
483 nfp_warn(app->cpp, "FlowerNIC requires eth table\n");
484 return -EINVAL;
485 }
486
487 if (!pf->mac_stats_bar) {
488 nfp_warn(app->cpp, "FlowerNIC requires mac_stats BAR\n");
489 return -EINVAL;
490 }
491
492 if (!pf->vf_cfg_bar) {
493 nfp_warn(app->cpp, "FlowerNIC requires vf_cfg BAR\n");
494 return -EINVAL;
495 }
496
8a276873
PJV
497 version = nfp_rtsym_read_le(app->pf->rtbl, "hw_flower_version", &err);
498 if (err) {
499 nfp_warn(app->cpp, "FlowerNIC requires hw_flower_version memory symbol\n");
500 return err;
501 }
502
12ecf615
PJV
503 ctx_count = nfp_rtsym_read_le(app->pf->rtbl, "CONFIG_FC_HOST_CTX_COUNT",
504 &err);
505 if (err) {
506 nfp_warn(app->cpp,
507 "FlowerNIC: unsupported host context count: %d\n",
508 err);
509 err = 0;
510 ctx_count = BIT(17);
511 }
512
8a276873
PJV
513 /* We need to ensure hardware has enough flower capabilities. */
514 if (version != NFP_FLOWER_ALLOWED_VER) {
515 nfp_warn(app->cpp, "FlowerNIC: unsupported firmware version\n");
516 return -EINVAL;
517 }
518
b985f870
SH
519 app_priv = vzalloc(sizeof(struct nfp_flower_priv));
520 if (!app_priv)
9ce6bbbb
JK
521 return -ENOMEM;
522
12ecf615 523 app_priv->stats_ring_size = roundup_pow_of_two(ctx_count);
b985f870 524 app->priv = app_priv;
c496291c 525 app_priv->app = app;
cf2cbadc
PJV
526 skb_queue_head_init(&app_priv->cmsg_skbs_high);
527 skb_queue_head_init(&app_priv->cmsg_skbs_low);
b985f870 528 INIT_WORK(&app_priv->cmsg_work, nfp_flower_cmsg_process_rx);
d2c2928d 529 init_waitqueue_head(&app_priv->reify_wait_queue);
b985f870 530
29a5dcae
JH
531 init_waitqueue_head(&app_priv->mtu_conf.wait_q);
532 spin_lock_init(&app_priv->mtu_conf.lock);
533
12ecf615 534 err = nfp_flower_metadata_init(app, ctx_count);
43f84b72
PJV
535 if (err)
536 goto err_free_app_priv;
537
73997348
JH
538 /* Extract the extra features supported by the firmware. */
539 features = nfp_rtsym_read_le(app->pf->rtbl,
540 "_abi_flower_extra_features", &err);
541 if (err)
542 app_priv->flower_ext_feats = 0;
543 else
544 app_priv->flower_ext_feats = features;
545
898bc7d6
JH
546 /* Tell the firmware that the driver supports lag. */
547 err = nfp_rtsym_write_le(app->pf->rtbl,
548 "_abi_flower_balance_sync_enable", 1);
bb9a8d03 549 if (!err) {
898bc7d6 550 app_priv->flower_ext_feats |= NFP_FL_FEATS_LAG;
bb9a8d03
JH
551 nfp_flower_lag_init(&app_priv->nfp_lag);
552 } else if (err == -ENOENT) {
898bc7d6 553 nfp_warn(app->cpp, "LAG not supported by FW.\n");
bb9a8d03 554 } else {
898bc7d6 555 goto err_cleanup_metadata;
bb9a8d03 556 }
898bc7d6 557
3166dd07
JH
558 INIT_LIST_HEAD(&app_priv->indr_block_cb_priv);
559
1025351a 560 return 0;
43f84b72 561
898bc7d6
JH
562err_cleanup_metadata:
563 nfp_flower_metadata_cleanup(app);
43f84b72
PJV
564err_free_app_priv:
565 vfree(app->priv);
566 return err;
1025351a
SH
567}
568
9ce6bbbb
JK
569static void nfp_flower_clean(struct nfp_app *app)
570{
b985f870
SH
571 struct nfp_flower_priv *app_priv = app->priv;
572
cf2cbadc
PJV
573 skb_queue_purge(&app_priv->cmsg_skbs_high);
574 skb_queue_purge(&app_priv->cmsg_skbs_low);
b985f870
SH
575 flush_work(&app_priv->cmsg_work);
576
bb9a8d03
JH
577 if (app_priv->flower_ext_feats & NFP_FL_FEATS_LAG)
578 nfp_flower_lag_cleanup(&app_priv->nfp_lag);
579
df7c7dd2 580 nfp_flower_metadata_cleanup(app);
43f84b72 581 vfree(app->priv);
9ce6bbbb
JK
582 app->priv = NULL;
583}
584
29a5dcae
JH
585static bool nfp_flower_check_ack(struct nfp_flower_priv *app_priv)
586{
587 bool ret;
588
589 spin_lock_bh(&app_priv->mtu_conf.lock);
590 ret = app_priv->mtu_conf.ack;
591 spin_unlock_bh(&app_priv->mtu_conf.lock);
592
593 return ret;
594}
595
596static int
597nfp_flower_repr_change_mtu(struct nfp_app *app, struct net_device *netdev,
598 int new_mtu)
599{
600 struct nfp_flower_priv *app_priv = app->priv;
601 struct nfp_repr *repr = netdev_priv(netdev);
96439889 602 int err;
29a5dcae
JH
603
604 /* Only need to config FW for physical port MTU change. */
605 if (repr->port->type != NFP_PORT_PHYS_PORT)
606 return 0;
607
608 if (!(app_priv->flower_ext_feats & NFP_FL_NBI_MTU_SETTING)) {
609 nfp_err(app->cpp, "Physical port MTU setting not supported\n");
610 return -EINVAL;
611 }
612
613 spin_lock_bh(&app_priv->mtu_conf.lock);
614 app_priv->mtu_conf.ack = false;
615 app_priv->mtu_conf.requested_val = new_mtu;
616 app_priv->mtu_conf.portnum = repr->dst->u.port_info.port_id;
617 spin_unlock_bh(&app_priv->mtu_conf.lock);
618
619 err = nfp_flower_cmsg_portmod(repr, netif_carrier_ok(netdev), new_mtu,
620 true);
621 if (err) {
622 spin_lock_bh(&app_priv->mtu_conf.lock);
623 app_priv->mtu_conf.requested_val = 0;
624 spin_unlock_bh(&app_priv->mtu_conf.lock);
625 return err;
626 }
627
628 /* Wait for fw to ack the change. */
96439889
FL
629 if (!wait_event_timeout(app_priv->mtu_conf.wait_q,
630 nfp_flower_check_ack(app_priv),
631 NFP_FL_REPLY_TIMEOUT)) {
29a5dcae
JH
632 spin_lock_bh(&app_priv->mtu_conf.lock);
633 app_priv->mtu_conf.requested_val = 0;
634 spin_unlock_bh(&app_priv->mtu_conf.lock);
635 nfp_warn(app->cpp, "MTU change not verified with fw\n");
636 return -EIO;
637 }
638
639 return 0;
640}
641
fd0dd1ab
JH
642static int nfp_flower_start(struct nfp_app *app)
643{
bb9a8d03
JH
644 struct nfp_flower_priv *app_priv = app->priv;
645 int err;
646
647 if (app_priv->flower_ext_feats & NFP_FL_FEATS_LAG) {
648 err = nfp_flower_lag_reset(&app_priv->nfp_lag);
649 if (err)
650 return err;
bb9a8d03
JH
651 }
652
fd0dd1ab
JH
653 return nfp_tunnel_config_start(app);
654}
655
656static void nfp_flower_stop(struct nfp_app *app)
0c665e2b
JK
657{
658 nfp_tunnel_config_stop(app);
659}
660
661static int
662nfp_flower_netdev_event(struct nfp_app *app, struct net_device *netdev,
663 unsigned long event, void *ptr)
fd0dd1ab 664{
bb9a8d03 665 struct nfp_flower_priv *app_priv = app->priv;
0c665e2b 666 int ret;
bb9a8d03 667
0c665e2b
JK
668 if (app_priv->flower_ext_feats & NFP_FL_FEATS_LAG) {
669 ret = nfp_flower_lag_netdev_event(app_priv, netdev, event, ptr);
670 if (ret & NOTIFY_STOP_MASK)
671 return ret;
672 }
bb9a8d03 673
3166dd07
JH
674 ret = nfp_flower_reg_indir_block_handler(app, netdev, event);
675 if (ret & NOTIFY_STOP_MASK)
676 return ret;
677
0c665e2b 678 return nfp_tunnel_mac_event_handler(app, netdev, event, ptr);
fd0dd1ab
JH
679}
680
1025351a
SH
681const struct nfp_app_type app_flower = {
682 .id = NFP_APP_FLOWER_NIC,
683 .name = "flower",
78a0a65f
JK
684
685 .ctrl_cap_mask = ~0U,
1025351a
SH
686 .ctrl_has_meta = true,
687
688 .extra_cap = nfp_flower_extra_cap,
689
690 .init = nfp_flower_init,
9ce6bbbb 691 .clean = nfp_flower_clean,
1025351a 692
29a5dcae
JH
693 .repr_change_mtu = nfp_flower_repr_change_mtu,
694
c496291c 695 .vnic_alloc = nfp_flower_vnic_alloc,
1025351a 696 .vnic_init = nfp_flower_vnic_init,
c496291c 697 .vnic_clean = nfp_flower_vnic_clean,
1025351a 698
d2c2928d 699 .repr_preclean = nfp_flower_repr_netdev_preclean,
1a24d4f9
JH
700 .repr_clean = nfp_flower_repr_netdev_clean,
701
5d7c64a7
JK
702 .repr_open = nfp_flower_repr_netdev_open,
703 .repr_stop = nfp_flower_repr_netdev_stop,
704
fd0dd1ab
JH
705 .start = nfp_flower_start,
706 .stop = nfp_flower_stop,
707
0c665e2b
JK
708 .netdev_event = nfp_flower_netdev_event,
709
1025351a
SH
710 .ctrl_msg_rx = nfp_flower_cmsg_rx,
711
24a021ed
SH
712 .sriov_enable = nfp_flower_sriov_enable,
713 .sriov_disable = nfp_flower_sriov_disable,
714
1025351a
SH
715 .eswitch_mode_get = eswitch_mode_get,
716 .repr_get = nfp_flower_repr_get,
8a276873
PJV
717
718 .setup_tc = nfp_flower_setup_tc,
1025351a 719};