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/io-64-nonatomic-hi-lo.h>
0006 #include <linux/lockdep.h>
0007 #include <net/dst_metadata.h>
0008 
0009 #include "nfpcore/nfp_cpp.h"
0010 #include "nfpcore/nfp_nsp.h"
0011 #include "nfp_app.h"
0012 #include "nfp_main.h"
0013 #include "nfp_net.h"
0014 #include "nfp_net_ctrl.h"
0015 #include "nfp_net_repr.h"
0016 #include "nfp_net_sriov.h"
0017 #include "nfp_port.h"
0018 
0019 struct net_device *
0020 nfp_repr_get_locked(struct nfp_app *app, struct nfp_reprs *set, unsigned int id)
0021 {
0022     return rcu_dereference_protected(set->reprs[id],
0023                      nfp_app_is_locked(app));
0024 }
0025 
0026 static void
0027 nfp_repr_inc_tx_stats(struct net_device *netdev, unsigned int len,
0028               int tx_status)
0029 {
0030     struct nfp_repr *repr = netdev_priv(netdev);
0031     struct nfp_repr_pcpu_stats *stats;
0032 
0033     if (unlikely(tx_status != NET_XMIT_SUCCESS &&
0034              tx_status != NET_XMIT_CN)) {
0035         this_cpu_inc(repr->stats->tx_drops);
0036         return;
0037     }
0038 
0039     stats = this_cpu_ptr(repr->stats);
0040     u64_stats_update_begin(&stats->syncp);
0041     stats->tx_packets++;
0042     stats->tx_bytes += len;
0043     u64_stats_update_end(&stats->syncp);
0044 }
0045 
0046 void nfp_repr_inc_rx_stats(struct net_device *netdev, unsigned int len)
0047 {
0048     struct nfp_repr *repr = netdev_priv(netdev);
0049     struct nfp_repr_pcpu_stats *stats;
0050 
0051     stats = this_cpu_ptr(repr->stats);
0052     u64_stats_update_begin(&stats->syncp);
0053     stats->rx_packets++;
0054     stats->rx_bytes += len;
0055     u64_stats_update_end(&stats->syncp);
0056 }
0057 
0058 static void
0059 nfp_repr_phy_port_get_stats64(struct nfp_port *port,
0060                   struct rtnl_link_stats64 *stats)
0061 {
0062     u8 __iomem *mem = port->eth_stats;
0063 
0064     stats->tx_packets = readq(mem + NFP_MAC_STATS_TX_FRAMES_TRANSMITTED_OK);
0065     stats->tx_bytes = readq(mem + NFP_MAC_STATS_TX_OUT_OCTETS);
0066     stats->tx_dropped = readq(mem + NFP_MAC_STATS_TX_OUT_ERRORS);
0067 
0068     stats->rx_packets = readq(mem + NFP_MAC_STATS_RX_FRAMES_RECEIVED_OK);
0069     stats->rx_bytes = readq(mem + NFP_MAC_STATS_RX_IN_OCTETS);
0070     stats->rx_dropped = readq(mem + NFP_MAC_STATS_RX_IN_ERRORS);
0071 }
0072 
0073 static void
0074 nfp_repr_vnic_get_stats64(struct nfp_port *port,
0075               struct rtnl_link_stats64 *stats)
0076 {
0077     /* TX and RX stats are flipped as we are returning the stats as seen
0078      * at the switch port corresponding to the VF.
0079      */
0080     stats->tx_packets = readq(port->vnic + NFP_NET_CFG_STATS_RX_FRAMES);
0081     stats->tx_bytes = readq(port->vnic + NFP_NET_CFG_STATS_RX_OCTETS);
0082     stats->tx_dropped = readq(port->vnic + NFP_NET_CFG_STATS_RX_DISCARDS);
0083 
0084     stats->rx_packets = readq(port->vnic + NFP_NET_CFG_STATS_TX_FRAMES);
0085     stats->rx_bytes = readq(port->vnic + NFP_NET_CFG_STATS_TX_OCTETS);
0086     stats->rx_dropped = readq(port->vnic + NFP_NET_CFG_STATS_TX_DISCARDS);
0087 }
0088 
0089 static void
0090 nfp_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
0091 {
0092     struct nfp_repr *repr = netdev_priv(netdev);
0093 
0094     if (WARN_ON(!repr->port))
0095         return;
0096 
0097     switch (repr->port->type) {
0098     case NFP_PORT_PHYS_PORT:
0099         if (!__nfp_port_get_eth_port(repr->port))
0100             break;
0101         nfp_repr_phy_port_get_stats64(repr->port, stats);
0102         break;
0103     case NFP_PORT_PF_PORT:
0104     case NFP_PORT_VF_PORT:
0105         nfp_repr_vnic_get_stats64(repr->port, stats);
0106         break;
0107     default:
0108         break;
0109     }
0110 }
0111 
0112 static bool
0113 nfp_repr_has_offload_stats(const struct net_device *dev, int attr_id)
0114 {
0115     switch (attr_id) {
0116     case IFLA_OFFLOAD_XSTATS_CPU_HIT:
0117         return true;
0118     }
0119 
0120     return false;
0121 }
0122 
0123 static int
0124 nfp_repr_get_host_stats64(const struct net_device *netdev,
0125               struct rtnl_link_stats64 *stats)
0126 {
0127     struct nfp_repr *repr = netdev_priv(netdev);
0128     int i;
0129 
0130     for_each_possible_cpu(i) {
0131         u64 tbytes, tpkts, tdrops, rbytes, rpkts;
0132         struct nfp_repr_pcpu_stats *repr_stats;
0133         unsigned int start;
0134 
0135         repr_stats = per_cpu_ptr(repr->stats, i);
0136         do {
0137             start = u64_stats_fetch_begin_irq(&repr_stats->syncp);
0138             tbytes = repr_stats->tx_bytes;
0139             tpkts = repr_stats->tx_packets;
0140             tdrops = repr_stats->tx_drops;
0141             rbytes = repr_stats->rx_bytes;
0142             rpkts = repr_stats->rx_packets;
0143         } while (u64_stats_fetch_retry_irq(&repr_stats->syncp, start));
0144 
0145         stats->tx_bytes += tbytes;
0146         stats->tx_packets += tpkts;
0147         stats->tx_dropped += tdrops;
0148         stats->rx_bytes += rbytes;
0149         stats->rx_packets += rpkts;
0150     }
0151 
0152     return 0;
0153 }
0154 
0155 static int
0156 nfp_repr_get_offload_stats(int attr_id, const struct net_device *dev,
0157                void *stats)
0158 {
0159     switch (attr_id) {
0160     case IFLA_OFFLOAD_XSTATS_CPU_HIT:
0161         return nfp_repr_get_host_stats64(dev, stats);
0162     }
0163 
0164     return -EINVAL;
0165 }
0166 
0167 static int nfp_repr_change_mtu(struct net_device *netdev, int new_mtu)
0168 {
0169     struct nfp_repr *repr = netdev_priv(netdev);
0170     int err;
0171 
0172     err = nfp_app_check_mtu(repr->app, netdev, new_mtu);
0173     if (err)
0174         return err;
0175 
0176     err = nfp_app_repr_change_mtu(repr->app, netdev, new_mtu);
0177     if (err)
0178         return err;
0179 
0180     netdev->mtu = new_mtu;
0181 
0182     return 0;
0183 }
0184 
0185 static netdev_tx_t nfp_repr_xmit(struct sk_buff *skb, struct net_device *netdev)
0186 {
0187     struct nfp_repr *repr = netdev_priv(netdev);
0188     unsigned int len = skb->len;
0189     int ret;
0190 
0191     skb_dst_drop(skb);
0192     dst_hold((struct dst_entry *)repr->dst);
0193     skb_dst_set(skb, (struct dst_entry *)repr->dst);
0194     skb->dev = repr->dst->u.port_info.lower_dev;
0195 
0196     ret = dev_queue_xmit(skb);
0197     nfp_repr_inc_tx_stats(netdev, len, ret);
0198 
0199     return NETDEV_TX_OK;
0200 }
0201 
0202 static int nfp_repr_stop(struct net_device *netdev)
0203 {
0204     struct nfp_repr *repr = netdev_priv(netdev);
0205     int err;
0206 
0207     err = nfp_app_repr_stop(repr->app, repr);
0208     if (err)
0209         return err;
0210 
0211     nfp_port_configure(netdev, false);
0212     return 0;
0213 }
0214 
0215 static int nfp_repr_open(struct net_device *netdev)
0216 {
0217     struct nfp_repr *repr = netdev_priv(netdev);
0218     int err;
0219 
0220     err = nfp_port_configure(netdev, true);
0221     if (err)
0222         return err;
0223 
0224     err = nfp_app_repr_open(repr->app, repr);
0225     if (err)
0226         goto err_port_disable;
0227 
0228     return 0;
0229 
0230 err_port_disable:
0231     nfp_port_configure(netdev, false);
0232     return err;
0233 }
0234 
0235 static netdev_features_t
0236 nfp_repr_fix_features(struct net_device *netdev, netdev_features_t features)
0237 {
0238     struct nfp_repr *repr = netdev_priv(netdev);
0239     netdev_features_t old_features = features;
0240     netdev_features_t lower_features;
0241     struct net_device *lower_dev;
0242 
0243     lower_dev = repr->dst->u.port_info.lower_dev;
0244 
0245     lower_features = lower_dev->features;
0246     if (lower_features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM))
0247         lower_features |= NETIF_F_HW_CSUM;
0248 
0249     features = netdev_intersect_features(features, lower_features);
0250     features |= old_features & (NETIF_F_SOFT_FEATURES | NETIF_F_HW_TC);
0251     features |= NETIF_F_LLTX;
0252 
0253     return features;
0254 }
0255 
0256 const struct net_device_ops nfp_repr_netdev_ops = {
0257     .ndo_init       = nfp_app_ndo_init,
0258     .ndo_uninit     = nfp_app_ndo_uninit,
0259     .ndo_open       = nfp_repr_open,
0260     .ndo_stop       = nfp_repr_stop,
0261     .ndo_start_xmit     = nfp_repr_xmit,
0262     .ndo_change_mtu     = nfp_repr_change_mtu,
0263     .ndo_get_stats64    = nfp_repr_get_stats64,
0264     .ndo_has_offload_stats  = nfp_repr_has_offload_stats,
0265     .ndo_get_offload_stats  = nfp_repr_get_offload_stats,
0266     .ndo_get_phys_port_name = nfp_port_get_phys_port_name,
0267     .ndo_setup_tc       = nfp_port_setup_tc,
0268     .ndo_set_vf_mac     = nfp_app_set_vf_mac,
0269     .ndo_set_vf_vlan    = nfp_app_set_vf_vlan,
0270     .ndo_set_vf_spoofchk    = nfp_app_set_vf_spoofchk,
0271     .ndo_set_vf_trust   = nfp_app_set_vf_trust,
0272     .ndo_get_vf_config  = nfp_app_get_vf_config,
0273     .ndo_set_vf_link_state  = nfp_app_set_vf_link_state,
0274     .ndo_fix_features   = nfp_repr_fix_features,
0275     .ndo_set_features   = nfp_port_set_features,
0276     .ndo_set_mac_address    = eth_mac_addr,
0277     .ndo_get_port_parent_id = nfp_port_get_port_parent_id,
0278     .ndo_get_devlink_port   = nfp_devlink_get_devlink_port,
0279 };
0280 
0281 void
0282 nfp_repr_transfer_features(struct net_device *netdev, struct net_device *lower)
0283 {
0284     struct nfp_repr *repr = netdev_priv(netdev);
0285 
0286     if (repr->dst->u.port_info.lower_dev != lower)
0287         return;
0288 
0289     netif_inherit_tso_max(netdev, lower);
0290 
0291     netdev_update_features(netdev);
0292 }
0293 
0294 static void nfp_repr_clean(struct nfp_repr *repr)
0295 {
0296     unregister_netdev(repr->netdev);
0297     nfp_app_repr_clean(repr->app, repr->netdev);
0298     dst_release((struct dst_entry *)repr->dst);
0299     nfp_port_free(repr->port);
0300 }
0301 
0302 static struct lock_class_key nfp_repr_netdev_xmit_lock_key;
0303 
0304 static void nfp_repr_set_lockdep_class_one(struct net_device *dev,
0305                        struct netdev_queue *txq,
0306                        void *_unused)
0307 {
0308     lockdep_set_class(&txq->_xmit_lock, &nfp_repr_netdev_xmit_lock_key);
0309 }
0310 
0311 static void nfp_repr_set_lockdep_class(struct net_device *dev)
0312 {
0313     netdev_for_each_tx_queue(dev, nfp_repr_set_lockdep_class_one, NULL);
0314 }
0315 
0316 int nfp_repr_init(struct nfp_app *app, struct net_device *netdev,
0317           u32 cmsg_port_id, struct nfp_port *port,
0318           struct net_device *pf_netdev)
0319 {
0320     struct nfp_repr *repr = netdev_priv(netdev);
0321     struct nfp_net *nn = netdev_priv(pf_netdev);
0322     u32 repr_cap = nn->tlv_caps.repr_cap;
0323     int err;
0324 
0325     nfp_repr_set_lockdep_class(netdev);
0326 
0327     repr->port = port;
0328     repr->dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, GFP_KERNEL);
0329     if (!repr->dst)
0330         return -ENOMEM;
0331     repr->dst->u.port_info.port_id = cmsg_port_id;
0332     repr->dst->u.port_info.lower_dev = pf_netdev;
0333 
0334     netdev->netdev_ops = &nfp_repr_netdev_ops;
0335     netdev->ethtool_ops = &nfp_port_ethtool_ops;
0336 
0337     netdev->max_mtu = pf_netdev->max_mtu;
0338 
0339     /* Set features the lower device can support with representors */
0340     if (repr_cap & NFP_NET_CFG_CTRL_LIVE_ADDR)
0341         netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
0342 
0343     netdev->hw_features = NETIF_F_HIGHDMA;
0344     if (repr_cap & NFP_NET_CFG_CTRL_RXCSUM_ANY)
0345         netdev->hw_features |= NETIF_F_RXCSUM;
0346     if (repr_cap & NFP_NET_CFG_CTRL_TXCSUM)
0347         netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
0348     if (repr_cap & NFP_NET_CFG_CTRL_GATHER)
0349         netdev->hw_features |= NETIF_F_SG;
0350     if ((repr_cap & NFP_NET_CFG_CTRL_LSO && nn->fw_ver.major > 2) ||
0351         repr_cap & NFP_NET_CFG_CTRL_LSO2)
0352         netdev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6;
0353     if (repr_cap & NFP_NET_CFG_CTRL_RSS_ANY)
0354         netdev->hw_features |= NETIF_F_RXHASH;
0355     if (repr_cap & NFP_NET_CFG_CTRL_VXLAN) {
0356         if (repr_cap & NFP_NET_CFG_CTRL_LSO)
0357             netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
0358     }
0359     if (repr_cap & NFP_NET_CFG_CTRL_NVGRE) {
0360         if (repr_cap & NFP_NET_CFG_CTRL_LSO)
0361             netdev->hw_features |= NETIF_F_GSO_GRE;
0362     }
0363     if (repr_cap & (NFP_NET_CFG_CTRL_VXLAN | NFP_NET_CFG_CTRL_NVGRE))
0364         netdev->hw_enc_features = netdev->hw_features;
0365 
0366     netdev->vlan_features = netdev->hw_features;
0367 
0368     if (repr_cap & NFP_NET_CFG_CTRL_RXVLAN_ANY)
0369         netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
0370     if (repr_cap & NFP_NET_CFG_CTRL_TXVLAN_ANY) {
0371         if (repr_cap & NFP_NET_CFG_CTRL_LSO2)
0372             netdev_warn(netdev, "Device advertises both TSO2 and TXVLAN. Refusing to enable TXVLAN.\n");
0373         else
0374             netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX;
0375     }
0376     if (repr_cap & NFP_NET_CFG_CTRL_CTAG_FILTER)
0377         netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
0378     if (repr_cap & NFP_NET_CFG_CTRL_RXQINQ)
0379         netdev->hw_features |= NETIF_F_HW_VLAN_STAG_RX;
0380 
0381     netdev->features = netdev->hw_features;
0382 
0383     /* C-Tag strip and S-Tag strip can't be supported simultaneously,
0384      * so enable C-Tag strip and disable S-Tag strip by default.
0385      */
0386     netdev->features &= ~NETIF_F_HW_VLAN_STAG_RX;
0387     netif_set_tso_max_segs(netdev, NFP_NET_LSO_MAX_SEGS);
0388 
0389     netdev->priv_flags |= IFF_NO_QUEUE | IFF_DISABLE_NETPOLL;
0390     netdev->features |= NETIF_F_LLTX;
0391 
0392     if (nfp_app_has_tc(app)) {
0393         netdev->features |= NETIF_F_HW_TC;
0394         netdev->hw_features |= NETIF_F_HW_TC;
0395     }
0396 
0397     err = nfp_app_repr_init(app, netdev);
0398     if (err)
0399         goto err_clean;
0400 
0401     err = register_netdev(netdev);
0402     if (err)
0403         goto err_repr_clean;
0404 
0405     return 0;
0406 
0407 err_repr_clean:
0408     nfp_app_repr_clean(app, netdev);
0409 err_clean:
0410     dst_release((struct dst_entry *)repr->dst);
0411     return err;
0412 }
0413 
0414 static void __nfp_repr_free(struct nfp_repr *repr)
0415 {
0416     free_percpu(repr->stats);
0417     free_netdev(repr->netdev);
0418 }
0419 
0420 void nfp_repr_free(struct net_device *netdev)
0421 {
0422     __nfp_repr_free(netdev_priv(netdev));
0423 }
0424 
0425 struct net_device *
0426 nfp_repr_alloc_mqs(struct nfp_app *app, unsigned int txqs, unsigned int rxqs)
0427 {
0428     struct net_device *netdev;
0429     struct nfp_repr *repr;
0430 
0431     netdev = alloc_etherdev_mqs(sizeof(*repr), txqs, rxqs);
0432     if (!netdev)
0433         return NULL;
0434 
0435     netif_carrier_off(netdev);
0436 
0437     repr = netdev_priv(netdev);
0438     repr->netdev = netdev;
0439     repr->app = app;
0440 
0441     repr->stats = netdev_alloc_pcpu_stats(struct nfp_repr_pcpu_stats);
0442     if (!repr->stats)
0443         goto err_free_netdev;
0444 
0445     return netdev;
0446 
0447 err_free_netdev:
0448     free_netdev(netdev);
0449     return NULL;
0450 }
0451 
0452 void nfp_repr_clean_and_free(struct nfp_repr *repr)
0453 {
0454     nfp_info(repr->app->cpp, "Destroying Representor(%s)\n",
0455          repr->netdev->name);
0456     nfp_repr_clean(repr);
0457     __nfp_repr_free(repr);
0458 }
0459 
0460 void nfp_reprs_clean_and_free(struct nfp_app *app, struct nfp_reprs *reprs)
0461 {
0462     struct net_device *netdev;
0463     unsigned int i;
0464 
0465     for (i = 0; i < reprs->num_reprs; i++) {
0466         netdev = nfp_repr_get_locked(app, reprs, i);
0467         if (netdev)
0468             nfp_repr_clean_and_free(netdev_priv(netdev));
0469     }
0470 
0471     kfree(reprs);
0472 }
0473 
0474 void
0475 nfp_reprs_clean_and_free_by_type(struct nfp_app *app, enum nfp_repr_type type)
0476 {
0477     struct net_device *netdev;
0478     struct nfp_reprs *reprs;
0479     int i;
0480 
0481     reprs = rcu_dereference_protected(app->reprs[type],
0482                       nfp_app_is_locked(app));
0483     if (!reprs)
0484         return;
0485 
0486     /* Preclean must happen before we remove the reprs reference from the
0487      * app below.
0488      */
0489     for (i = 0; i < reprs->num_reprs; i++) {
0490         netdev = nfp_repr_get_locked(app, reprs, i);
0491         if (netdev)
0492             nfp_app_repr_preclean(app, netdev);
0493     }
0494 
0495     reprs = nfp_app_reprs_set(app, type, NULL);
0496 
0497     synchronize_rcu();
0498     nfp_reprs_clean_and_free(app, reprs);
0499 }
0500 
0501 struct nfp_reprs *nfp_reprs_alloc(unsigned int num_reprs)
0502 {
0503     struct nfp_reprs *reprs;
0504 
0505     reprs = kzalloc(struct_size(reprs, reprs, num_reprs), GFP_KERNEL);
0506     if (!reprs)
0507         return NULL;
0508     reprs->num_reprs = num_reprs;
0509 
0510     return reprs;
0511 }
0512 
0513 int nfp_reprs_resync_phys_ports(struct nfp_app *app)
0514 {
0515     struct net_device *netdev;
0516     struct nfp_reprs *reprs;
0517     struct nfp_repr *repr;
0518     int i;
0519 
0520     reprs = nfp_reprs_get_locked(app, NFP_REPR_TYPE_PHYS_PORT);
0521     if (!reprs)
0522         return 0;
0523 
0524     for (i = 0; i < reprs->num_reprs; i++) {
0525         netdev = nfp_repr_get_locked(app, reprs, i);
0526         if (!netdev)
0527             continue;
0528 
0529         repr = netdev_priv(netdev);
0530         if (repr->port->type != NFP_PORT_INVALID)
0531             continue;
0532 
0533         nfp_app_repr_preclean(app, netdev);
0534         rtnl_lock();
0535         rcu_assign_pointer(reprs->reprs[i], NULL);
0536         rtnl_unlock();
0537         synchronize_rcu();
0538         nfp_repr_clean(repr);
0539     }
0540 
0541     return 0;
0542 }