2 * Copyright (C) 2017 Netronome Systems, Inc.
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.
9 * The BSD 2-Clause License:
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
15 * 1. Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
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.
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
34 #include <linux/etherdevice.h>
35 #include <linux/lockdep.h>
36 #include <linux/pci.h>
37 #include <linux/skbuff.h>
38 #include <linux/vmalloc.h>
39 #include <net/devlink.h>
40 #include <net/dst_metadata.h>
43 #include "../nfpcore/nfp_cpp.h"
44 #include "../nfpcore/nfp_nffw.h"
45 #include "../nfpcore/nfp_nsp.h"
46 #include "../nfp_app.h"
47 #include "../nfp_main.h"
48 #include "../nfp_net.h"
49 #include "../nfp_net_repr.h"
50 #include "../nfp_port.h"
53 #define NFP_FLOWER_ALLOWED_VER 0x0001000000010000UL
55 #define NFP_FLOWER_FRAME_HEADROOM 158
57 static const char *nfp_flower_extra_cap(struct nfp_app
*app
, struct nfp_net
*nn
)
62 static enum devlink_eswitch_mode
eswitch_mode_get(struct nfp_app
*app
)
64 return DEVLINK_ESWITCH_MODE_SWITCHDEV
;
67 static enum nfp_repr_type
68 nfp_flower_repr_get_type_and_port(struct nfp_app
*app
, u32 port_id
, u8
*port
)
70 switch (FIELD_GET(NFP_FLOWER_CMSG_PORT_TYPE
, port_id
)) {
71 case NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT
:
72 *port
= FIELD_GET(NFP_FLOWER_CMSG_PORT_PHYS_PORT_NUM
,
74 return NFP_REPR_TYPE_PHYS_PORT
;
76 case NFP_FLOWER_CMSG_PORT_TYPE_PCIE_PORT
:
77 *port
= FIELD_GET(NFP_FLOWER_CMSG_PORT_VNIC
, port_id
);
78 if (FIELD_GET(NFP_FLOWER_CMSG_PORT_VNIC_TYPE
, port_id
) ==
79 NFP_FLOWER_CMSG_PORT_VNIC_TYPE_PF
)
80 return NFP_REPR_TYPE_PF
;
82 return NFP_REPR_TYPE_VF
;
85 return NFP_FLOWER_CMSG_PORT_TYPE_UNSPEC
;
88 static struct net_device
*
89 nfp_flower_repr_get(struct nfp_app
*app
, u32 port_id
)
91 enum nfp_repr_type repr_type
;
92 struct nfp_reprs
*reprs
;
95 repr_type
= nfp_flower_repr_get_type_and_port(app
, port_id
, &port
);
97 reprs
= rcu_dereference(app
->reprs
[repr_type
]);
101 if (port
>= reprs
->num_reprs
)
104 return rcu_dereference(reprs
->reprs
[port
]);
108 nfp_flower_reprs_reify(struct nfp_app
*app
, enum nfp_repr_type type
,
111 struct nfp_reprs
*reprs
;
112 int i
, err
, count
= 0;
114 reprs
= rcu_dereference_protected(app
->reprs
[type
],
115 lockdep_is_held(&app
->pf
->lock
));
119 for (i
= 0; i
< reprs
->num_reprs
; i
++) {
120 struct net_device
*netdev
;
122 netdev
= nfp_repr_get_locked(app
, reprs
, i
);
124 struct nfp_repr
*repr
= netdev_priv(netdev
);
126 err
= nfp_flower_cmsg_portreify(repr
, exists
);
137 nfp_flower_wait_repr_reify(struct nfp_app
*app
, atomic_t
*replies
, int tot_repl
)
139 struct nfp_flower_priv
*priv
= app
->priv
;
145 lockdep_assert_held(&app
->pf
->lock
);
146 err
= wait_event_interruptible_timeout(priv
->reify_wait_queue
,
147 atomic_read(replies
) >= tot_repl
,
148 msecs_to_jiffies(10));
150 nfp_warn(app
->cpp
, "Not all reprs responded to reify\n");
158 nfp_flower_repr_netdev_open(struct nfp_app
*app
, struct nfp_repr
*repr
)
162 err
= nfp_flower_cmsg_portmod(repr
, true, repr
->netdev
->mtu
, false);
166 netif_tx_wake_all_queues(repr
->netdev
);
172 nfp_flower_repr_netdev_stop(struct nfp_app
*app
, struct nfp_repr
*repr
)
174 netif_tx_disable(repr
->netdev
);
176 return nfp_flower_cmsg_portmod(repr
, false, repr
->netdev
->mtu
, false);
180 nfp_flower_repr_netdev_init(struct nfp_app
*app
, struct net_device
*netdev
)
182 return tc_setup_cb_egdev_register(netdev
,
183 nfp_flower_setup_tc_egress_cb
,
184 netdev_priv(netdev
));
188 nfp_flower_repr_netdev_clean(struct nfp_app
*app
, struct net_device
*netdev
)
190 tc_setup_cb_egdev_unregister(netdev
, nfp_flower_setup_tc_egress_cb
,
191 netdev_priv(netdev
));
195 nfp_flower_repr_netdev_preclean(struct nfp_app
*app
, struct net_device
*netdev
)
197 struct nfp_repr
*repr
= netdev_priv(netdev
);
198 struct nfp_flower_priv
*priv
= app
->priv
;
199 atomic_t
*replies
= &priv
->reify_replies
;
202 atomic_set(replies
, 0);
203 err
= nfp_flower_cmsg_portreify(repr
, false);
205 nfp_warn(app
->cpp
, "Failed to notify firmware about repr destruction\n");
209 nfp_flower_wait_repr_reify(app
, replies
, 1);
212 static void nfp_flower_sriov_disable(struct nfp_app
*app
)
214 struct nfp_flower_priv
*priv
= app
->priv
;
219 nfp_reprs_clean_and_free_by_type(app
, NFP_REPR_TYPE_VF
);
223 nfp_flower_spawn_vnic_reprs(struct nfp_app
*app
,
224 enum nfp_flower_cmsg_port_vnic_type vnic_type
,
225 enum nfp_repr_type repr_type
, unsigned int cnt
)
227 u8 nfp_pcie
= nfp_cppcore_pcie_unit(app
->pf
->cpp
);
228 struct nfp_flower_priv
*priv
= app
->priv
;
229 atomic_t
*replies
= &priv
->reify_replies
;
230 enum nfp_port_type port_type
;
231 struct nfp_reprs
*reprs
;
232 int i
, err
, reify_cnt
;
235 port_type
= repr_type
== NFP_REPR_TYPE_PF
? NFP_PORT_PF_PORT
:
238 reprs
= nfp_reprs_alloc(cnt
);
242 for (i
= 0; i
< cnt
; i
++) {
243 struct net_device
*repr
;
244 struct nfp_port
*port
;
247 repr
= nfp_repr_alloc(app
);
250 goto err_reprs_clean
;
252 RCU_INIT_POINTER(reprs
->reprs
[i
], repr
);
254 /* For now we only support 1 PF */
255 WARN_ON(repr_type
== NFP_REPR_TYPE_PF
&& i
);
257 port
= nfp_port_alloc(app
, port_type
, repr
);
258 if (repr_type
== NFP_REPR_TYPE_PF
) {
260 port
->vnic
= priv
->nn
->dp
.ctrl_bar
;
265 app
->pf
->vf_cfg_mem
+ i
* NFP_NET_CFG_BAR_SZ
;
268 eth_hw_addr_random(repr
);
270 port_id
= nfp_flower_cmsg_pcie_port(nfp_pcie
, vnic_type
,
272 err
= nfp_repr_init(app
, repr
,
273 port_id
, port
, priv
->nn
->dp
.netdev
);
276 goto err_reprs_clean
;
279 nfp_info(app
->cpp
, "%s%d Representor(%s) created\n",
280 repr_type
== NFP_REPR_TYPE_PF
? "PF" : "VF", i
,
284 nfp_app_reprs_set(app
, repr_type
, reprs
);
286 atomic_set(replies
, 0);
287 reify_cnt
= nfp_flower_reprs_reify(app
, repr_type
, true);
290 nfp_warn(app
->cpp
, "Failed to notify firmware about repr creation\n");
291 goto err_reprs_remove
;
294 err
= nfp_flower_wait_repr_reify(app
, replies
, reify_cnt
);
296 goto err_reprs_remove
;
300 reprs
= nfp_app_reprs_set(app
, repr_type
, NULL
);
302 nfp_reprs_clean_and_free(app
, reprs
);
306 static int nfp_flower_sriov_enable(struct nfp_app
*app
, int num_vfs
)
308 struct nfp_flower_priv
*priv
= app
->priv
;
313 return nfp_flower_spawn_vnic_reprs(app
,
314 NFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF
,
315 NFP_REPR_TYPE_VF
, num_vfs
);
319 nfp_flower_spawn_phy_reprs(struct nfp_app
*app
, struct nfp_flower_priv
*priv
)
321 struct nfp_eth_table
*eth_tbl
= app
->pf
->eth_tbl
;
322 atomic_t
*replies
= &priv
->reify_replies
;
323 struct sk_buff
*ctrl_skb
;
324 struct nfp_reprs
*reprs
;
328 ctrl_skb
= nfp_flower_cmsg_mac_repr_start(app
, eth_tbl
->count
);
332 reprs
= nfp_reprs_alloc(eth_tbl
->max_index
+ 1);
335 goto err_free_ctrl_skb
;
338 for (i
= 0; i
< eth_tbl
->count
; i
++) {
339 unsigned int phys_port
= eth_tbl
->ports
[i
].index
;
340 struct net_device
*repr
;
341 struct nfp_port
*port
;
344 repr
= nfp_repr_alloc(app
);
347 goto err_reprs_clean
;
349 RCU_INIT_POINTER(reprs
->reprs
[phys_port
], repr
);
351 port
= nfp_port_alloc(app
, NFP_PORT_PHYS_PORT
, repr
);
354 goto err_reprs_clean
;
356 err
= nfp_port_init_phy_port(app
->pf
, app
, port
, i
);
359 goto err_reprs_clean
;
362 SET_NETDEV_DEV(repr
, &priv
->nn
->pdev
->dev
);
363 nfp_net_get_mac_addr(app
->pf
, port
);
365 cmsg_port_id
= nfp_flower_cmsg_phys_port(phys_port
);
366 err
= nfp_repr_init(app
, repr
,
367 cmsg_port_id
, port
, priv
->nn
->dp
.netdev
);
370 goto err_reprs_clean
;
373 nfp_flower_cmsg_mac_repr_add(ctrl_skb
, i
,
374 eth_tbl
->ports
[i
].nbi
,
375 eth_tbl
->ports
[i
].base
,
378 nfp_info(app
->cpp
, "Phys Port %d Representor(%s) created\n",
379 phys_port
, repr
->name
);
382 nfp_app_reprs_set(app
, NFP_REPR_TYPE_PHYS_PORT
, reprs
);
384 /* The REIFY/MAC_REPR control messages should be sent after the MAC
385 * representors are registered using nfp_app_reprs_set(). This is
386 * because the firmware may respond with control messages for the
387 * MAC representors, f.e. to provide the driver with information
388 * about their state, and without registration the driver will drop
391 atomic_set(replies
, 0);
392 reify_cnt
= nfp_flower_reprs_reify(app
, NFP_REPR_TYPE_PHYS_PORT
, true);
395 nfp_warn(app
->cpp
, "Failed to notify firmware about repr creation\n");
396 goto err_reprs_remove
;
399 err
= nfp_flower_wait_repr_reify(app
, replies
, reify_cnt
);
401 goto err_reprs_remove
;
403 nfp_ctrl_tx(app
->ctrl
, ctrl_skb
);
407 reprs
= nfp_app_reprs_set(app
, NFP_REPR_TYPE_PHYS_PORT
, NULL
);
409 nfp_reprs_clean_and_free(app
, reprs
);
415 static int nfp_flower_vnic_alloc(struct nfp_app
*app
, struct nfp_net
*nn
,
419 nfp_warn(app
->cpp
, "FlowerNIC doesn't support more than one data vNIC\n");
420 goto err_invalid_port
;
423 eth_hw_addr_random(nn
->dp
.netdev
);
424 netif_keep_dst(nn
->dp
.netdev
);
429 nn
->port
= nfp_port_alloc(app
, NFP_PORT_INVALID
, nn
->dp
.netdev
);
430 return PTR_ERR_OR_ZERO(nn
->port
);
433 static void nfp_flower_vnic_clean(struct nfp_app
*app
, struct nfp_net
*nn
)
435 struct nfp_flower_priv
*priv
= app
->priv
;
437 if (app
->pf
->num_vfs
)
438 nfp_reprs_clean_and_free_by_type(app
, NFP_REPR_TYPE_VF
);
439 nfp_reprs_clean_and_free_by_type(app
, NFP_REPR_TYPE_PF
);
440 nfp_reprs_clean_and_free_by_type(app
, NFP_REPR_TYPE_PHYS_PORT
);
445 static int nfp_flower_vnic_init(struct nfp_app
*app
, struct nfp_net
*nn
)
447 struct nfp_flower_priv
*priv
= app
->priv
;
452 err
= nfp_flower_spawn_phy_reprs(app
, app
->priv
);
456 err
= nfp_flower_spawn_vnic_reprs(app
,
457 NFP_FLOWER_CMSG_PORT_VNIC_TYPE_PF
,
458 NFP_REPR_TYPE_PF
, 1);
460 goto err_destroy_reprs_phy
;
462 if (app
->pf
->num_vfs
) {
463 err
= nfp_flower_spawn_vnic_reprs(app
,
464 NFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF
,
468 goto err_destroy_reprs_pf
;
473 err_destroy_reprs_pf
:
474 nfp_reprs_clean_and_free_by_type(app
, NFP_REPR_TYPE_PF
);
475 err_destroy_reprs_phy
:
476 nfp_reprs_clean_and_free_by_type(app
, NFP_REPR_TYPE_PHYS_PORT
);
482 static int nfp_flower_init(struct nfp_app
*app
)
484 const struct nfp_pf
*pf
= app
->pf
;
485 struct nfp_flower_priv
*app_priv
;
486 u64 version
, features
;
490 nfp_warn(app
->cpp
, "FlowerNIC requires eth table\n");
494 if (!pf
->mac_stats_bar
) {
495 nfp_warn(app
->cpp
, "FlowerNIC requires mac_stats BAR\n");
499 if (!pf
->vf_cfg_bar
) {
500 nfp_warn(app
->cpp
, "FlowerNIC requires vf_cfg BAR\n");
504 version
= nfp_rtsym_read_le(app
->pf
->rtbl
, "hw_flower_version", &err
);
506 nfp_warn(app
->cpp
, "FlowerNIC requires hw_flower_version memory symbol\n");
510 /* We need to ensure hardware has enough flower capabilities. */
511 if (version
!= NFP_FLOWER_ALLOWED_VER
) {
512 nfp_warn(app
->cpp
, "FlowerNIC: unsupported firmware version\n");
516 app_priv
= vzalloc(sizeof(struct nfp_flower_priv
));
520 app
->priv
= app_priv
;
522 skb_queue_head_init(&app_priv
->cmsg_skbs_high
);
523 skb_queue_head_init(&app_priv
->cmsg_skbs_low
);
524 INIT_WORK(&app_priv
->cmsg_work
, nfp_flower_cmsg_process_rx
);
525 init_waitqueue_head(&app_priv
->reify_wait_queue
);
527 init_waitqueue_head(&app_priv
->mtu_conf
.wait_q
);
528 spin_lock_init(&app_priv
->mtu_conf
.lock
);
530 err
= nfp_flower_metadata_init(app
);
532 goto err_free_app_priv
;
534 /* Extract the extra features supported by the firmware. */
535 features
= nfp_rtsym_read_le(app
->pf
->rtbl
,
536 "_abi_flower_extra_features", &err
);
538 app_priv
->flower_ext_feats
= 0;
540 app_priv
->flower_ext_feats
= features
;
549 static void nfp_flower_clean(struct nfp_app
*app
)
551 struct nfp_flower_priv
*app_priv
= app
->priv
;
553 skb_queue_purge(&app_priv
->cmsg_skbs_high
);
554 skb_queue_purge(&app_priv
->cmsg_skbs_low
);
555 flush_work(&app_priv
->cmsg_work
);
557 nfp_flower_metadata_cleanup(app
);
563 nfp_flower_check_mtu(struct nfp_app
*app
, struct net_device
*netdev
,
566 /* The flower fw reserves NFP_FLOWER_FRAME_HEADROOM bytes of the
567 * supported max MTU to allow for appending tunnel headers. To prevent
568 * unexpected behaviour this needs to be accounted for.
570 if (new_mtu
> netdev
->max_mtu
- NFP_FLOWER_FRAME_HEADROOM
) {
571 nfp_err(app
->cpp
, "New MTU (%d) is not valid\n", new_mtu
);
578 static bool nfp_flower_check_ack(struct nfp_flower_priv
*app_priv
)
582 spin_lock_bh(&app_priv
->mtu_conf
.lock
);
583 ret
= app_priv
->mtu_conf
.ack
;
584 spin_unlock_bh(&app_priv
->mtu_conf
.lock
);
590 nfp_flower_repr_change_mtu(struct nfp_app
*app
, struct net_device
*netdev
,
593 struct nfp_flower_priv
*app_priv
= app
->priv
;
594 struct nfp_repr
*repr
= netdev_priv(netdev
);
597 /* Only need to config FW for physical port MTU change. */
598 if (repr
->port
->type
!= NFP_PORT_PHYS_PORT
)
601 if (!(app_priv
->flower_ext_feats
& NFP_FL_NBI_MTU_SETTING
)) {
602 nfp_err(app
->cpp
, "Physical port MTU setting not supported\n");
606 spin_lock_bh(&app_priv
->mtu_conf
.lock
);
607 app_priv
->mtu_conf
.ack
= false;
608 app_priv
->mtu_conf
.requested_val
= new_mtu
;
609 app_priv
->mtu_conf
.portnum
= repr
->dst
->u
.port_info
.port_id
;
610 spin_unlock_bh(&app_priv
->mtu_conf
.lock
);
612 err
= nfp_flower_cmsg_portmod(repr
, netif_carrier_ok(netdev
), new_mtu
,
615 spin_lock_bh(&app_priv
->mtu_conf
.lock
);
616 app_priv
->mtu_conf
.requested_val
= 0;
617 spin_unlock_bh(&app_priv
->mtu_conf
.lock
);
621 /* Wait for fw to ack the change. */
622 ack
= wait_event_timeout(app_priv
->mtu_conf
.wait_q
,
623 nfp_flower_check_ack(app_priv
),
624 msecs_to_jiffies(10));
627 spin_lock_bh(&app_priv
->mtu_conf
.lock
);
628 app_priv
->mtu_conf
.requested_val
= 0;
629 spin_unlock_bh(&app_priv
->mtu_conf
.lock
);
630 nfp_warn(app
->cpp
, "MTU change not verified with fw\n");
637 static int nfp_flower_start(struct nfp_app
*app
)
639 return nfp_tunnel_config_start(app
);
642 static void nfp_flower_stop(struct nfp_app
*app
)
644 nfp_tunnel_config_stop(app
);
647 const struct nfp_app_type app_flower
= {
648 .id
= NFP_APP_FLOWER_NIC
,
651 .ctrl_cap_mask
= ~0U,
652 .ctrl_has_meta
= true,
654 .extra_cap
= nfp_flower_extra_cap
,
656 .init
= nfp_flower_init
,
657 .clean
= nfp_flower_clean
,
659 .check_mtu
= nfp_flower_check_mtu
,
660 .repr_change_mtu
= nfp_flower_repr_change_mtu
,
662 .vnic_alloc
= nfp_flower_vnic_alloc
,
663 .vnic_init
= nfp_flower_vnic_init
,
664 .vnic_clean
= nfp_flower_vnic_clean
,
666 .repr_init
= nfp_flower_repr_netdev_init
,
667 .repr_preclean
= nfp_flower_repr_netdev_preclean
,
668 .repr_clean
= nfp_flower_repr_netdev_clean
,
670 .repr_open
= nfp_flower_repr_netdev_open
,
671 .repr_stop
= nfp_flower_repr_netdev_stop
,
673 .start
= nfp_flower_start
,
674 .stop
= nfp_flower_stop
,
676 .ctrl_msg_rx
= nfp_flower_cmsg_rx
,
678 .sriov_enable
= nfp_flower_sriov_enable
,
679 .sriov_disable
= nfp_flower_sriov_disable
,
681 .eswitch_mode_get
= eswitch_mode_get
,
682 .repr_get
= nfp_flower_repr_get
,
684 .setup_tc
= nfp_flower_setup_tc
,