Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
0002 /* Copyright (C) 2017-2018 Netronome Systems, Inc. */
0003 
0004 #include <linux/etherdevice.h>
0005 #include <linux/lockdep.h>
0006 #include <linux/pci.h>
0007 #include <linux/skbuff.h>
0008 #include <linux/vmalloc.h>
0009 #include <net/devlink.h>
0010 #include <net/dst_metadata.h>
0011 
0012 #include "main.h"
0013 #include "../nfpcore/nfp_cpp.h"
0014 #include "../nfpcore/nfp_nffw.h"
0015 #include "../nfpcore/nfp_nsp.h"
0016 #include "../nfp_app.h"
0017 #include "../nfp_main.h"
0018 #include "../nfp_net.h"
0019 #include "../nfp_net_repr.h"
0020 #include "../nfp_port.h"
0021 #include "./cmsg.h"
0022 
0023 #define NFP_FLOWER_ALLOWED_VER 0x0001000000010000UL
0024 
0025 #define NFP_MIN_INT_PORT_ID 1
0026 #define NFP_MAX_INT_PORT_ID 256
0027 
0028 static const char *nfp_flower_extra_cap(struct nfp_app *app, struct nfp_net *nn)
0029 {
0030     return "FLOWER";
0031 }
0032 
0033 static enum devlink_eswitch_mode eswitch_mode_get(struct nfp_app *app)
0034 {
0035     return DEVLINK_ESWITCH_MODE_SWITCHDEV;
0036 }
0037 
0038 static int
0039 nfp_flower_lookup_internal_port_id(struct nfp_flower_priv *priv,
0040                    struct net_device *netdev)
0041 {
0042     struct net_device *entry;
0043     int i, id = 0;
0044 
0045     rcu_read_lock();
0046     idr_for_each_entry(&priv->internal_ports.port_ids, entry, i)
0047         if (entry == netdev) {
0048             id = i;
0049             break;
0050         }
0051     rcu_read_unlock();
0052 
0053     return id;
0054 }
0055 
0056 static int
0057 nfp_flower_get_internal_port_id(struct nfp_app *app, struct net_device *netdev)
0058 {
0059     struct nfp_flower_priv *priv = app->priv;
0060     int id;
0061 
0062     id = nfp_flower_lookup_internal_port_id(priv, netdev);
0063     if (id > 0)
0064         return id;
0065 
0066     idr_preload(GFP_ATOMIC);
0067     spin_lock_bh(&priv->internal_ports.lock);
0068     id = idr_alloc(&priv->internal_ports.port_ids, netdev,
0069                NFP_MIN_INT_PORT_ID, NFP_MAX_INT_PORT_ID, GFP_ATOMIC);
0070     spin_unlock_bh(&priv->internal_ports.lock);
0071     idr_preload_end();
0072 
0073     return id;
0074 }
0075 
0076 u32 nfp_flower_get_port_id_from_netdev(struct nfp_app *app,
0077                        struct net_device *netdev)
0078 {
0079     int ext_port;
0080 
0081     if (nfp_netdev_is_nfp_repr(netdev)) {
0082         return nfp_repr_get_port_id(netdev);
0083     } else if (nfp_flower_internal_port_can_offload(app, netdev)) {
0084         ext_port = nfp_flower_get_internal_port_id(app, netdev);
0085         if (ext_port < 0)
0086             return 0;
0087 
0088         return nfp_flower_internal_port_get_port_id(ext_port);
0089     }
0090 
0091     return 0;
0092 }
0093 
0094 static struct net_device *
0095 nfp_flower_get_netdev_from_internal_port_id(struct nfp_app *app, int port_id)
0096 {
0097     struct nfp_flower_priv *priv = app->priv;
0098     struct net_device *netdev;
0099 
0100     rcu_read_lock();
0101     netdev = idr_find(&priv->internal_ports.port_ids, port_id);
0102     rcu_read_unlock();
0103 
0104     return netdev;
0105 }
0106 
0107 static void
0108 nfp_flower_free_internal_port_id(struct nfp_app *app, struct net_device *netdev)
0109 {
0110     struct nfp_flower_priv *priv = app->priv;
0111     int id;
0112 
0113     id = nfp_flower_lookup_internal_port_id(priv, netdev);
0114     if (!id)
0115         return;
0116 
0117     spin_lock_bh(&priv->internal_ports.lock);
0118     idr_remove(&priv->internal_ports.port_ids, id);
0119     spin_unlock_bh(&priv->internal_ports.lock);
0120 }
0121 
0122 static int
0123 nfp_flower_internal_port_event_handler(struct nfp_app *app,
0124                        struct net_device *netdev,
0125                        unsigned long event)
0126 {
0127     if (event == NETDEV_UNREGISTER &&
0128         nfp_flower_internal_port_can_offload(app, netdev))
0129         nfp_flower_free_internal_port_id(app, netdev);
0130 
0131     return NOTIFY_OK;
0132 }
0133 
0134 static void nfp_flower_internal_port_init(struct nfp_flower_priv *priv)
0135 {
0136     spin_lock_init(&priv->internal_ports.lock);
0137     idr_init(&priv->internal_ports.port_ids);
0138 }
0139 
0140 static void nfp_flower_internal_port_cleanup(struct nfp_flower_priv *priv)
0141 {
0142     idr_destroy(&priv->internal_ports.port_ids);
0143 }
0144 
0145 static struct nfp_flower_non_repr_priv *
0146 nfp_flower_non_repr_priv_lookup(struct nfp_app *app, struct net_device *netdev)
0147 {
0148     struct nfp_flower_priv *priv = app->priv;
0149     struct nfp_flower_non_repr_priv *entry;
0150 
0151     ASSERT_RTNL();
0152 
0153     list_for_each_entry(entry, &priv->non_repr_priv, list)
0154         if (entry->netdev == netdev)
0155             return entry;
0156 
0157     return NULL;
0158 }
0159 
0160 void
0161 __nfp_flower_non_repr_priv_get(struct nfp_flower_non_repr_priv *non_repr_priv)
0162 {
0163     non_repr_priv->ref_count++;
0164 }
0165 
0166 struct nfp_flower_non_repr_priv *
0167 nfp_flower_non_repr_priv_get(struct nfp_app *app, struct net_device *netdev)
0168 {
0169     struct nfp_flower_priv *priv = app->priv;
0170     struct nfp_flower_non_repr_priv *entry;
0171 
0172     entry = nfp_flower_non_repr_priv_lookup(app, netdev);
0173     if (entry)
0174         goto inc_ref;
0175 
0176     entry = kzalloc(sizeof(*entry), GFP_KERNEL);
0177     if (!entry)
0178         return NULL;
0179 
0180     entry->netdev = netdev;
0181     list_add(&entry->list, &priv->non_repr_priv);
0182 
0183 inc_ref:
0184     __nfp_flower_non_repr_priv_get(entry);
0185     return entry;
0186 }
0187 
0188 void
0189 __nfp_flower_non_repr_priv_put(struct nfp_flower_non_repr_priv *non_repr_priv)
0190 {
0191     if (--non_repr_priv->ref_count)
0192         return;
0193 
0194     list_del(&non_repr_priv->list);
0195     kfree(non_repr_priv);
0196 }
0197 
0198 void
0199 nfp_flower_non_repr_priv_put(struct nfp_app *app, struct net_device *netdev)
0200 {
0201     struct nfp_flower_non_repr_priv *entry;
0202 
0203     entry = nfp_flower_non_repr_priv_lookup(app, netdev);
0204     if (!entry)
0205         return;
0206 
0207     __nfp_flower_non_repr_priv_put(entry);
0208 }
0209 
0210 static enum nfp_repr_type
0211 nfp_flower_repr_get_type_and_port(struct nfp_app *app, u32 port_id, u8 *port)
0212 {
0213     switch (FIELD_GET(NFP_FLOWER_CMSG_PORT_TYPE, port_id)) {
0214     case NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT:
0215         *port = FIELD_GET(NFP_FLOWER_CMSG_PORT_PHYS_PORT_NUM,
0216                   port_id);
0217         return NFP_REPR_TYPE_PHYS_PORT;
0218 
0219     case NFP_FLOWER_CMSG_PORT_TYPE_PCIE_PORT:
0220         *port = FIELD_GET(NFP_FLOWER_CMSG_PORT_VNIC, port_id);
0221         if (FIELD_GET(NFP_FLOWER_CMSG_PORT_VNIC_TYPE, port_id) ==
0222             NFP_FLOWER_CMSG_PORT_VNIC_TYPE_PF)
0223             return NFP_REPR_TYPE_PF;
0224         else
0225             return NFP_REPR_TYPE_VF;
0226     }
0227 
0228     return __NFP_REPR_TYPE_MAX;
0229 }
0230 
0231 static struct net_device *
0232 nfp_flower_dev_get(struct nfp_app *app, u32 port_id, bool *redir_egress)
0233 {
0234     enum nfp_repr_type repr_type;
0235     struct nfp_reprs *reprs;
0236     u8 port = 0;
0237 
0238     /* Check if the port is internal. */
0239     if (FIELD_GET(NFP_FLOWER_CMSG_PORT_TYPE, port_id) ==
0240         NFP_FLOWER_CMSG_PORT_TYPE_OTHER_PORT) {
0241         if (redir_egress)
0242             *redir_egress = true;
0243         port = FIELD_GET(NFP_FLOWER_CMSG_PORT_PHYS_PORT_NUM, port_id);
0244         return nfp_flower_get_netdev_from_internal_port_id(app, port);
0245     }
0246 
0247     repr_type = nfp_flower_repr_get_type_and_port(app, port_id, &port);
0248     if (repr_type > NFP_REPR_TYPE_MAX)
0249         return NULL;
0250 
0251     reprs = rcu_dereference(app->reprs[repr_type]);
0252     if (!reprs)
0253         return NULL;
0254 
0255     if (port >= reprs->num_reprs)
0256         return NULL;
0257 
0258     return rcu_dereference(reprs->reprs[port]);
0259 }
0260 
0261 static int
0262 nfp_flower_reprs_reify(struct nfp_app *app, enum nfp_repr_type type,
0263                bool exists)
0264 {
0265     struct nfp_reprs *reprs;
0266     int i, err, count = 0;
0267 
0268     reprs = rcu_dereference_protected(app->reprs[type],
0269                       nfp_app_is_locked(app));
0270     if (!reprs)
0271         return 0;
0272 
0273     for (i = 0; i < reprs->num_reprs; i++) {
0274         struct net_device *netdev;
0275 
0276         netdev = nfp_repr_get_locked(app, reprs, i);
0277         if (netdev) {
0278             struct nfp_repr *repr = netdev_priv(netdev);
0279 
0280             err = nfp_flower_cmsg_portreify(repr, exists);
0281             if (err)
0282                 return err;
0283             count++;
0284         }
0285     }
0286 
0287     return count;
0288 }
0289 
0290 static int
0291 nfp_flower_wait_repr_reify(struct nfp_app *app, atomic_t *replies, int tot_repl)
0292 {
0293     struct nfp_flower_priv *priv = app->priv;
0294 
0295     if (!tot_repl)
0296         return 0;
0297 
0298     assert_nfp_app_locked(app);
0299     if (!wait_event_timeout(priv->reify_wait_queue,
0300                 atomic_read(replies) >= tot_repl,
0301                 NFP_FL_REPLY_TIMEOUT)) {
0302         nfp_warn(app->cpp, "Not all reprs responded to reify\n");
0303         return -EIO;
0304     }
0305 
0306     return 0;
0307 }
0308 
0309 static int
0310 nfp_flower_repr_netdev_open(struct nfp_app *app, struct nfp_repr *repr)
0311 {
0312     int err;
0313 
0314     err = nfp_flower_cmsg_portmod(repr, true, repr->netdev->mtu, false);
0315     if (err)
0316         return err;
0317 
0318     netif_tx_wake_all_queues(repr->netdev);
0319 
0320     return 0;
0321 }
0322 
0323 static int
0324 nfp_flower_repr_netdev_stop(struct nfp_app *app, struct nfp_repr *repr)
0325 {
0326     netif_tx_disable(repr->netdev);
0327 
0328     return nfp_flower_cmsg_portmod(repr, false, repr->netdev->mtu, false);
0329 }
0330 
0331 static void
0332 nfp_flower_repr_netdev_clean(struct nfp_app *app, struct net_device *netdev)
0333 {
0334     struct nfp_repr *repr = netdev_priv(netdev);
0335 
0336     kfree(repr->app_priv);
0337 }
0338 
0339 static void
0340 nfp_flower_repr_netdev_preclean(struct nfp_app *app, struct net_device *netdev)
0341 {
0342     struct nfp_repr *repr = netdev_priv(netdev);
0343     struct nfp_flower_priv *priv = app->priv;
0344     atomic_t *replies = &priv->reify_replies;
0345     int err;
0346 
0347     atomic_set(replies, 0);
0348     err = nfp_flower_cmsg_portreify(repr, false);
0349     if (err) {
0350         nfp_warn(app->cpp, "Failed to notify firmware about repr destruction\n");
0351         return;
0352     }
0353 
0354     nfp_flower_wait_repr_reify(app, replies, 1);
0355 }
0356 
0357 static void nfp_flower_sriov_disable(struct nfp_app *app)
0358 {
0359     struct nfp_flower_priv *priv = app->priv;
0360 
0361     if (!priv->nn)
0362         return;
0363 
0364     nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_VF);
0365 }
0366 
0367 static int
0368 nfp_flower_spawn_vnic_reprs(struct nfp_app *app,
0369                 enum nfp_flower_cmsg_port_vnic_type vnic_type,
0370                 enum nfp_repr_type repr_type, unsigned int cnt)
0371 {
0372     u8 nfp_pcie = nfp_cppcore_pcie_unit(app->pf->cpp);
0373     struct nfp_flower_priv *priv = app->priv;
0374     atomic_t *replies = &priv->reify_replies;
0375     struct nfp_flower_repr_priv *repr_priv;
0376     enum nfp_port_type port_type;
0377     struct nfp_repr *nfp_repr;
0378     struct nfp_reprs *reprs;
0379     int i, err, reify_cnt;
0380     const u8 queue = 0;
0381 
0382     port_type = repr_type == NFP_REPR_TYPE_PF ? NFP_PORT_PF_PORT :
0383                             NFP_PORT_VF_PORT;
0384 
0385     reprs = nfp_reprs_alloc(cnt);
0386     if (!reprs)
0387         return -ENOMEM;
0388 
0389     for (i = 0; i < cnt; i++) {
0390         struct net_device *repr;
0391         struct nfp_port *port;
0392         u32 port_id;
0393 
0394         repr = nfp_repr_alloc(app);
0395         if (!repr) {
0396             err = -ENOMEM;
0397             goto err_reprs_clean;
0398         }
0399 
0400         repr_priv = kzalloc(sizeof(*repr_priv), GFP_KERNEL);
0401         if (!repr_priv) {
0402             err = -ENOMEM;
0403             nfp_repr_free(repr);
0404             goto err_reprs_clean;
0405         }
0406 
0407         nfp_repr = netdev_priv(repr);
0408         nfp_repr->app_priv = repr_priv;
0409         repr_priv->nfp_repr = nfp_repr;
0410 
0411         /* For now we only support 1 PF */
0412         WARN_ON(repr_type == NFP_REPR_TYPE_PF && i);
0413 
0414         port = nfp_port_alloc(app, port_type, repr);
0415         if (IS_ERR(port)) {
0416             err = PTR_ERR(port);
0417             kfree(repr_priv);
0418             nfp_repr_free(repr);
0419             goto err_reprs_clean;
0420         }
0421         if (repr_type == NFP_REPR_TYPE_PF) {
0422             port->pf_id = i;
0423             port->vnic = priv->nn->dp.ctrl_bar;
0424         } else {
0425             port->pf_id = 0;
0426             port->vf_id = i;
0427             port->vnic =
0428                 app->pf->vf_cfg_mem + i * NFP_NET_CFG_BAR_SZ;
0429         }
0430 
0431         eth_hw_addr_random(repr);
0432 
0433         port_id = nfp_flower_cmsg_pcie_port(nfp_pcie, vnic_type,
0434                             i, queue);
0435         err = nfp_repr_init(app, repr,
0436                     port_id, port, priv->nn->dp.netdev);
0437         if (err) {
0438             kfree(repr_priv);
0439             nfp_port_free(port);
0440             nfp_repr_free(repr);
0441             goto err_reprs_clean;
0442         }
0443 
0444         RCU_INIT_POINTER(reprs->reprs[i], repr);
0445         nfp_info(app->cpp, "%s%d Representor(%s) created\n",
0446              repr_type == NFP_REPR_TYPE_PF ? "PF" : "VF", i,
0447              repr->name);
0448     }
0449 
0450     nfp_app_reprs_set(app, repr_type, reprs);
0451 
0452     atomic_set(replies, 0);
0453     reify_cnt = nfp_flower_reprs_reify(app, repr_type, true);
0454     if (reify_cnt < 0) {
0455         err = reify_cnt;
0456         nfp_warn(app->cpp, "Failed to notify firmware about repr creation\n");
0457         goto err_reprs_remove;
0458     }
0459 
0460     err = nfp_flower_wait_repr_reify(app, replies, reify_cnt);
0461     if (err)
0462         goto err_reprs_remove;
0463 
0464     return 0;
0465 err_reprs_remove:
0466     reprs = nfp_app_reprs_set(app, repr_type, NULL);
0467 err_reprs_clean:
0468     nfp_reprs_clean_and_free(app, reprs);
0469     return err;
0470 }
0471 
0472 static int nfp_flower_sriov_enable(struct nfp_app *app, int num_vfs)
0473 {
0474     struct nfp_flower_priv *priv = app->priv;
0475 
0476     if (!priv->nn)
0477         return 0;
0478 
0479     return nfp_flower_spawn_vnic_reprs(app,
0480                        NFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF,
0481                        NFP_REPR_TYPE_VF, num_vfs);
0482 }
0483 
0484 static int
0485 nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)
0486 {
0487     struct nfp_eth_table *eth_tbl = app->pf->eth_tbl;
0488     atomic_t *replies = &priv->reify_replies;
0489     struct nfp_flower_repr_priv *repr_priv;
0490     struct nfp_repr *nfp_repr;
0491     struct sk_buff *ctrl_skb;
0492     struct nfp_reprs *reprs;
0493     int err, reify_cnt;
0494     unsigned int i;
0495 
0496     ctrl_skb = nfp_flower_cmsg_mac_repr_start(app, eth_tbl->count);
0497     if (!ctrl_skb)
0498         return -ENOMEM;
0499 
0500     reprs = nfp_reprs_alloc(eth_tbl->max_index + 1);
0501     if (!reprs) {
0502         err = -ENOMEM;
0503         goto err_free_ctrl_skb;
0504     }
0505 
0506     for (i = 0; i < eth_tbl->count; i++) {
0507         unsigned int phys_port = eth_tbl->ports[i].index;
0508         struct net_device *repr;
0509         struct nfp_port *port;
0510         u32 cmsg_port_id;
0511 
0512         repr = nfp_repr_alloc(app);
0513         if (!repr) {
0514             err = -ENOMEM;
0515             goto err_reprs_clean;
0516         }
0517 
0518         repr_priv = kzalloc(sizeof(*repr_priv), GFP_KERNEL);
0519         if (!repr_priv) {
0520             err = -ENOMEM;
0521             nfp_repr_free(repr);
0522             goto err_reprs_clean;
0523         }
0524 
0525         nfp_repr = netdev_priv(repr);
0526         nfp_repr->app_priv = repr_priv;
0527         repr_priv->nfp_repr = nfp_repr;
0528 
0529         port = nfp_port_alloc(app, NFP_PORT_PHYS_PORT, repr);
0530         if (IS_ERR(port)) {
0531             err = PTR_ERR(port);
0532             kfree(repr_priv);
0533             nfp_repr_free(repr);
0534             goto err_reprs_clean;
0535         }
0536         err = nfp_port_init_phy_port(app->pf, app, port, i);
0537         if (err) {
0538             kfree(repr_priv);
0539             nfp_port_free(port);
0540             nfp_repr_free(repr);
0541             goto err_reprs_clean;
0542         }
0543 
0544         SET_NETDEV_DEV(repr, &priv->nn->pdev->dev);
0545         nfp_net_get_mac_addr(app->pf, repr, port);
0546 
0547         cmsg_port_id = nfp_flower_cmsg_phys_port(phys_port);
0548         err = nfp_repr_init(app, repr,
0549                     cmsg_port_id, port, priv->nn->dp.netdev);
0550         if (err) {
0551             kfree(repr_priv);
0552             nfp_port_free(port);
0553             nfp_repr_free(repr);
0554             goto err_reprs_clean;
0555         }
0556 
0557         nfp_flower_cmsg_mac_repr_add(ctrl_skb, i,
0558                          eth_tbl->ports[i].nbi,
0559                          eth_tbl->ports[i].base,
0560                          phys_port);
0561 
0562         RCU_INIT_POINTER(reprs->reprs[phys_port], repr);
0563         nfp_info(app->cpp, "Phys Port %d Representor(%s) created\n",
0564              phys_port, repr->name);
0565     }
0566 
0567     nfp_app_reprs_set(app, NFP_REPR_TYPE_PHYS_PORT, reprs);
0568 
0569     /* The REIFY/MAC_REPR control messages should be sent after the MAC
0570      * representors are registered using nfp_app_reprs_set().  This is
0571      * because the firmware may respond with control messages for the
0572      * MAC representors, f.e. to provide the driver with information
0573      * about their state, and without registration the driver will drop
0574      * any such messages.
0575      */
0576     atomic_set(replies, 0);
0577     reify_cnt = nfp_flower_reprs_reify(app, NFP_REPR_TYPE_PHYS_PORT, true);
0578     if (reify_cnt < 0) {
0579         err = reify_cnt;
0580         nfp_warn(app->cpp, "Failed to notify firmware about repr creation\n");
0581         goto err_reprs_remove;
0582     }
0583 
0584     err = nfp_flower_wait_repr_reify(app, replies, reify_cnt);
0585     if (err)
0586         goto err_reprs_remove;
0587 
0588     nfp_ctrl_tx(app->ctrl, ctrl_skb);
0589 
0590     return 0;
0591 err_reprs_remove:
0592     reprs = nfp_app_reprs_set(app, NFP_REPR_TYPE_PHYS_PORT, NULL);
0593 err_reprs_clean:
0594     nfp_reprs_clean_and_free(app, reprs);
0595 err_free_ctrl_skb:
0596     kfree_skb(ctrl_skb);
0597     return err;
0598 }
0599 
0600 static int nfp_flower_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
0601                  unsigned int id)
0602 {
0603     if (id > 0) {
0604         nfp_warn(app->cpp, "FlowerNIC doesn't support more than one data vNIC\n");
0605         goto err_invalid_port;
0606     }
0607 
0608     eth_hw_addr_random(nn->dp.netdev);
0609     netif_keep_dst(nn->dp.netdev);
0610     nn->vnic_no_name = true;
0611 
0612     return 0;
0613 
0614 err_invalid_port:
0615     nn->port = nfp_port_alloc(app, NFP_PORT_INVALID, nn->dp.netdev);
0616     return PTR_ERR_OR_ZERO(nn->port);
0617 }
0618 
0619 static void nfp_flower_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
0620 {
0621     struct nfp_flower_priv *priv = app->priv;
0622 
0623     if (app->pf->num_vfs)
0624         nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_VF);
0625     nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PF);
0626     nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PHYS_PORT);
0627 
0628     priv->nn = NULL;
0629 }
0630 
0631 static int nfp_flower_vnic_init(struct nfp_app *app, struct nfp_net *nn)
0632 {
0633     struct nfp_flower_priv *priv = app->priv;
0634     int err;
0635 
0636     priv->nn = nn;
0637 
0638     err = nfp_flower_spawn_phy_reprs(app, app->priv);
0639     if (err)
0640         goto err_clear_nn;
0641 
0642     err = nfp_flower_spawn_vnic_reprs(app,
0643                       NFP_FLOWER_CMSG_PORT_VNIC_TYPE_PF,
0644                       NFP_REPR_TYPE_PF, 1);
0645     if (err)
0646         goto err_destroy_reprs_phy;
0647 
0648     if (app->pf->num_vfs) {
0649         err = nfp_flower_spawn_vnic_reprs(app,
0650                           NFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF,
0651                           NFP_REPR_TYPE_VF,
0652                           app->pf->num_vfs);
0653         if (err)
0654             goto err_destroy_reprs_pf;
0655     }
0656 
0657     return 0;
0658 
0659 err_destroy_reprs_pf:
0660     nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PF);
0661 err_destroy_reprs_phy:
0662     nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PHYS_PORT);
0663 err_clear_nn:
0664     priv->nn = NULL;
0665     return err;
0666 }
0667 
0668 static void nfp_flower_wait_host_bit(struct nfp_app *app)
0669 {
0670     unsigned long err_at;
0671     u64 feat;
0672     int err;
0673 
0674     /* Wait for HOST_ACK flag bit to propagate */
0675     err_at = jiffies + msecs_to_jiffies(100);
0676     do {
0677         feat = nfp_rtsym_read_le(app->pf->rtbl,
0678                      "_abi_flower_combined_features_global",
0679                      &err);
0680         if (time_is_before_eq_jiffies(err_at)) {
0681             nfp_warn(app->cpp,
0682                  "HOST_ACK bit not propagated in FW.\n");
0683             break;
0684         }
0685         usleep_range(1000, 2000);
0686     } while (!err && !(feat & NFP_FL_FEATS_HOST_ACK));
0687 
0688     if (err)
0689         nfp_warn(app->cpp,
0690              "Could not read global features entry from FW\n");
0691 }
0692 
0693 static int nfp_flower_sync_feature_bits(struct nfp_app *app)
0694 {
0695     struct nfp_flower_priv *app_priv = app->priv;
0696     int err;
0697 
0698     /* Tell the firmware of the host supported features. */
0699     err = nfp_rtsym_write_le(app->pf->rtbl, "_abi_flower_host_mask",
0700                  app_priv->flower_ext_feats |
0701                  NFP_FL_FEATS_HOST_ACK);
0702     if (!err)
0703         nfp_flower_wait_host_bit(app);
0704     else if (err != -ENOENT)
0705         return err;
0706 
0707     /* Tell the firmware that the driver supports lag. */
0708     err = nfp_rtsym_write_le(app->pf->rtbl,
0709                  "_abi_flower_balance_sync_enable", 1);
0710     if (!err) {
0711         app_priv->flower_en_feats |= NFP_FL_ENABLE_LAG;
0712         nfp_flower_lag_init(&app_priv->nfp_lag);
0713     } else if (err == -ENOENT) {
0714         nfp_warn(app->cpp, "LAG not supported by FW.\n");
0715     } else {
0716         return err;
0717     }
0718 
0719     if (app_priv->flower_ext_feats & NFP_FL_FEATS_FLOW_MOD) {
0720         /* Tell the firmware that the driver supports flow merging. */
0721         err = nfp_rtsym_write_le(app->pf->rtbl,
0722                      "_abi_flower_merge_hint_enable", 1);
0723         if (!err) {
0724             app_priv->flower_en_feats |= NFP_FL_ENABLE_FLOW_MERGE;
0725             nfp_flower_internal_port_init(app_priv);
0726         } else if (err == -ENOENT) {
0727             nfp_warn(app->cpp,
0728                  "Flow merge not supported by FW.\n");
0729         } else {
0730             return err;
0731         }
0732     } else {
0733         nfp_warn(app->cpp, "Flow mod/merge not supported by FW.\n");
0734     }
0735 
0736     return 0;
0737 }
0738 
0739 static int nfp_flower_init(struct nfp_app *app)
0740 {
0741     u64 version, features, ctx_count, num_mems;
0742     const struct nfp_pf *pf = app->pf;
0743     struct nfp_flower_priv *app_priv;
0744     int err;
0745 
0746     if (!pf->eth_tbl) {
0747         nfp_warn(app->cpp, "FlowerNIC requires eth table\n");
0748         return -EINVAL;
0749     }
0750 
0751     if (!pf->mac_stats_bar) {
0752         nfp_warn(app->cpp, "FlowerNIC requires mac_stats BAR\n");
0753         return -EINVAL;
0754     }
0755 
0756     if (!pf->vf_cfg_bar) {
0757         nfp_warn(app->cpp, "FlowerNIC requires vf_cfg BAR\n");
0758         return -EINVAL;
0759     }
0760 
0761     version = nfp_rtsym_read_le(app->pf->rtbl, "hw_flower_version", &err);
0762     if (err) {
0763         nfp_warn(app->cpp, "FlowerNIC requires hw_flower_version memory symbol\n");
0764         return err;
0765     }
0766 
0767     num_mems = nfp_rtsym_read_le(app->pf->rtbl, "CONFIG_FC_HOST_CTX_SPLIT",
0768                      &err);
0769     if (err) {
0770         nfp_warn(app->cpp,
0771              "FlowerNIC: unsupported host context memory: %d\n",
0772              err);
0773         err = 0;
0774         num_mems = 1;
0775     }
0776 
0777     if (!FIELD_FIT(NFP_FL_STAT_ID_MU_NUM, num_mems) || !num_mems) {
0778         nfp_warn(app->cpp,
0779              "FlowerNIC: invalid host context memory: %llu\n",
0780              num_mems);
0781         return -EINVAL;
0782     }
0783 
0784     ctx_count = nfp_rtsym_read_le(app->pf->rtbl, "CONFIG_FC_HOST_CTX_COUNT",
0785                       &err);
0786     if (err) {
0787         nfp_warn(app->cpp,
0788              "FlowerNIC: unsupported host context count: %d\n",
0789              err);
0790         err = 0;
0791         ctx_count = BIT(17);
0792     }
0793 
0794     /* We need to ensure hardware has enough flower capabilities. */
0795     if (version != NFP_FLOWER_ALLOWED_VER) {
0796         nfp_warn(app->cpp, "FlowerNIC: unsupported firmware version\n");
0797         return -EINVAL;
0798     }
0799 
0800     app_priv = vzalloc(sizeof(struct nfp_flower_priv));
0801     if (!app_priv)
0802         return -ENOMEM;
0803 
0804     app_priv->total_mem_units = num_mems;
0805     app_priv->active_mem_unit = 0;
0806     app_priv->stats_ring_size = roundup_pow_of_two(ctx_count);
0807     app->priv = app_priv;
0808     app_priv->app = app;
0809     skb_queue_head_init(&app_priv->cmsg_skbs_high);
0810     skb_queue_head_init(&app_priv->cmsg_skbs_low);
0811     INIT_WORK(&app_priv->cmsg_work, nfp_flower_cmsg_process_rx);
0812     init_waitqueue_head(&app_priv->reify_wait_queue);
0813 
0814     init_waitqueue_head(&app_priv->mtu_conf.wait_q);
0815     spin_lock_init(&app_priv->mtu_conf.lock);
0816 
0817     err = nfp_flower_metadata_init(app, ctx_count, num_mems);
0818     if (err)
0819         goto err_free_app_priv;
0820 
0821     /* Extract the extra features supported by the firmware. */
0822     features = nfp_rtsym_read_le(app->pf->rtbl,
0823                      "_abi_flower_extra_features", &err);
0824     if (err)
0825         app_priv->flower_ext_feats = 0;
0826     else
0827         app_priv->flower_ext_feats = features & NFP_FL_FEATS_HOST;
0828 
0829     err = nfp_flower_sync_feature_bits(app);
0830     if (err)
0831         goto err_cleanup;
0832 
0833     if (app_priv->flower_ext_feats & NFP_FL_FEATS_VF_RLIM)
0834         nfp_flower_qos_init(app);
0835 
0836     INIT_LIST_HEAD(&app_priv->indr_block_cb_priv);
0837     INIT_LIST_HEAD(&app_priv->non_repr_priv);
0838     app_priv->pre_tun_rule_cnt = 0;
0839 
0840     return 0;
0841 
0842 err_cleanup:
0843     if (app_priv->flower_en_feats & NFP_FL_ENABLE_LAG)
0844         nfp_flower_lag_cleanup(&app_priv->nfp_lag);
0845     nfp_flower_metadata_cleanup(app);
0846 err_free_app_priv:
0847     vfree(app->priv);
0848     return err;
0849 }
0850 
0851 static void nfp_flower_clean(struct nfp_app *app)
0852 {
0853     struct nfp_flower_priv *app_priv = app->priv;
0854 
0855     skb_queue_purge(&app_priv->cmsg_skbs_high);
0856     skb_queue_purge(&app_priv->cmsg_skbs_low);
0857     flush_work(&app_priv->cmsg_work);
0858 
0859     if (app_priv->flower_ext_feats & NFP_FL_FEATS_VF_RLIM)
0860         nfp_flower_qos_cleanup(app);
0861 
0862     if (app_priv->flower_en_feats & NFP_FL_ENABLE_LAG)
0863         nfp_flower_lag_cleanup(&app_priv->nfp_lag);
0864 
0865     if (app_priv->flower_en_feats & NFP_FL_ENABLE_FLOW_MERGE)
0866         nfp_flower_internal_port_cleanup(app_priv);
0867 
0868     nfp_flower_metadata_cleanup(app);
0869     vfree(app->priv);
0870     app->priv = NULL;
0871 }
0872 
0873 static bool nfp_flower_check_ack(struct nfp_flower_priv *app_priv)
0874 {
0875     bool ret;
0876 
0877     spin_lock_bh(&app_priv->mtu_conf.lock);
0878     ret = app_priv->mtu_conf.ack;
0879     spin_unlock_bh(&app_priv->mtu_conf.lock);
0880 
0881     return ret;
0882 }
0883 
0884 static int
0885 nfp_flower_repr_change_mtu(struct nfp_app *app, struct net_device *netdev,
0886                int new_mtu)
0887 {
0888     struct nfp_flower_priv *app_priv = app->priv;
0889     struct nfp_repr *repr = netdev_priv(netdev);
0890     int err;
0891 
0892     /* Only need to config FW for physical port MTU change. */
0893     if (repr->port->type != NFP_PORT_PHYS_PORT)
0894         return 0;
0895 
0896     if (!(app_priv->flower_ext_feats & NFP_FL_NBI_MTU_SETTING)) {
0897         nfp_err(app->cpp, "Physical port MTU setting not supported\n");
0898         return -EINVAL;
0899     }
0900 
0901     spin_lock_bh(&app_priv->mtu_conf.lock);
0902     app_priv->mtu_conf.ack = false;
0903     app_priv->mtu_conf.requested_val = new_mtu;
0904     app_priv->mtu_conf.portnum = repr->dst->u.port_info.port_id;
0905     spin_unlock_bh(&app_priv->mtu_conf.lock);
0906 
0907     err = nfp_flower_cmsg_portmod(repr, netif_carrier_ok(netdev), new_mtu,
0908                       true);
0909     if (err) {
0910         spin_lock_bh(&app_priv->mtu_conf.lock);
0911         app_priv->mtu_conf.requested_val = 0;
0912         spin_unlock_bh(&app_priv->mtu_conf.lock);
0913         return err;
0914     }
0915 
0916     /* Wait for fw to ack the change. */
0917     if (!wait_event_timeout(app_priv->mtu_conf.wait_q,
0918                 nfp_flower_check_ack(app_priv),
0919                 NFP_FL_REPLY_TIMEOUT)) {
0920         spin_lock_bh(&app_priv->mtu_conf.lock);
0921         app_priv->mtu_conf.requested_val = 0;
0922         spin_unlock_bh(&app_priv->mtu_conf.lock);
0923         nfp_warn(app->cpp, "MTU change not verified with fw\n");
0924         return -EIO;
0925     }
0926 
0927     return 0;
0928 }
0929 
0930 static int nfp_flower_start(struct nfp_app *app)
0931 {
0932     struct nfp_flower_priv *app_priv = app->priv;
0933     int err;
0934 
0935     if (app_priv->flower_en_feats & NFP_FL_ENABLE_LAG) {
0936         err = nfp_flower_lag_reset(&app_priv->nfp_lag);
0937         if (err)
0938             return err;
0939     }
0940 
0941     err = flow_indr_dev_register(nfp_flower_indr_setup_tc_cb, app);
0942     if (err)
0943         return err;
0944 
0945     err = nfp_tunnel_config_start(app);
0946     if (err)
0947         goto err_tunnel_config;
0948 
0949     return 0;
0950 
0951 err_tunnel_config:
0952     flow_indr_dev_unregister(nfp_flower_indr_setup_tc_cb, app,
0953                  nfp_flower_setup_indr_tc_release);
0954     return err;
0955 }
0956 
0957 static void nfp_flower_stop(struct nfp_app *app)
0958 {
0959     nfp_tunnel_config_stop(app);
0960 
0961     flow_indr_dev_unregister(nfp_flower_indr_setup_tc_cb, app,
0962                  nfp_flower_setup_indr_tc_release);
0963 }
0964 
0965 static int
0966 nfp_flower_netdev_event(struct nfp_app *app, struct net_device *netdev,
0967             unsigned long event, void *ptr)
0968 {
0969     struct nfp_flower_priv *app_priv = app->priv;
0970     int ret;
0971 
0972     if (app_priv->flower_en_feats & NFP_FL_ENABLE_LAG) {
0973         ret = nfp_flower_lag_netdev_event(app_priv, netdev, event, ptr);
0974         if (ret & NOTIFY_STOP_MASK)
0975             return ret;
0976     }
0977 
0978     ret = nfp_flower_internal_port_event_handler(app, netdev, event);
0979     if (ret & NOTIFY_STOP_MASK)
0980         return ret;
0981 
0982     return nfp_tunnel_mac_event_handler(app, netdev, event, ptr);
0983 }
0984 
0985 const struct nfp_app_type app_flower = {
0986     .id     = NFP_APP_FLOWER_NIC,
0987     .name       = "flower",
0988 
0989     .ctrl_cap_mask  = ~0U,
0990     .ctrl_has_meta  = true,
0991 
0992     .extra_cap  = nfp_flower_extra_cap,
0993 
0994     .init       = nfp_flower_init,
0995     .clean      = nfp_flower_clean,
0996 
0997     .repr_change_mtu  = nfp_flower_repr_change_mtu,
0998 
0999     .vnic_alloc = nfp_flower_vnic_alloc,
1000     .vnic_init  = nfp_flower_vnic_init,
1001     .vnic_clean = nfp_flower_vnic_clean,
1002 
1003     .repr_preclean  = nfp_flower_repr_netdev_preclean,
1004     .repr_clean = nfp_flower_repr_netdev_clean,
1005 
1006     .repr_open  = nfp_flower_repr_netdev_open,
1007     .repr_stop  = nfp_flower_repr_netdev_stop,
1008 
1009     .start      = nfp_flower_start,
1010     .stop       = nfp_flower_stop,
1011 
1012     .netdev_event   = nfp_flower_netdev_event,
1013 
1014     .ctrl_msg_rx    = nfp_flower_cmsg_rx,
1015 
1016     .sriov_enable   = nfp_flower_sriov_enable,
1017     .sriov_disable  = nfp_flower_sriov_disable,
1018 
1019     .eswitch_mode_get  = eswitch_mode_get,
1020     .dev_get    = nfp_flower_dev_get,
1021 
1022     .setup_tc   = nfp_flower_setup_tc,
1023 };