linux/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
<<
>>
Prefs
   1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
   2/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
   3
   4#include <linux/etherdevice.h>
   5#include <linux/io-64-nonatomic-hi-lo.h>
   6#include <linux/lockdep.h>
   7#include <net/dst_metadata.h>
   8
   9#include "nfpcore/nfp_cpp.h"
  10#include "nfpcore/nfp_nsp.h"
  11#include "nfp_app.h"
  12#include "nfp_main.h"
  13#include "nfp_net.h"
  14#include "nfp_net_ctrl.h"
  15#include "nfp_net_repr.h"
  16#include "nfp_net_sriov.h"
  17#include "nfp_port.h"
  18
  19struct net_device *
  20nfp_repr_get_locked(struct nfp_app *app, struct nfp_reprs *set, unsigned int id)
  21{
  22        return rcu_dereference_protected(set->reprs[id],
  23                                         lockdep_is_held(&app->pf->lock));
  24}
  25
  26static void
  27nfp_repr_inc_tx_stats(struct net_device *netdev, unsigned int len,
  28                      int tx_status)
  29{
  30        struct nfp_repr *repr = netdev_priv(netdev);
  31        struct nfp_repr_pcpu_stats *stats;
  32
  33        if (unlikely(tx_status != NET_XMIT_SUCCESS &&
  34                     tx_status != NET_XMIT_CN)) {
  35                this_cpu_inc(repr->stats->tx_drops);
  36                return;
  37        }
  38
  39        stats = this_cpu_ptr(repr->stats);
  40        u64_stats_update_begin(&stats->syncp);
  41        stats->tx_packets++;
  42        stats->tx_bytes += len;
  43        u64_stats_update_end(&stats->syncp);
  44}
  45
  46void nfp_repr_inc_rx_stats(struct net_device *netdev, unsigned int len)
  47{
  48        struct nfp_repr *repr = netdev_priv(netdev);
  49        struct nfp_repr_pcpu_stats *stats;
  50
  51        stats = this_cpu_ptr(repr->stats);
  52        u64_stats_update_begin(&stats->syncp);
  53        stats->rx_packets++;
  54        stats->rx_bytes += len;
  55        u64_stats_update_end(&stats->syncp);
  56}
  57
  58static void
  59nfp_repr_phy_port_get_stats64(struct nfp_port *port,
  60                              struct rtnl_link_stats64 *stats)
  61{
  62        u8 __iomem *mem = port->eth_stats;
  63
  64        stats->tx_packets = readq(mem + NFP_MAC_STATS_TX_FRAMES_TRANSMITTED_OK);
  65        stats->tx_bytes = readq(mem + NFP_MAC_STATS_TX_OUT_OCTETS);
  66        stats->tx_dropped = readq(mem + NFP_MAC_STATS_TX_OUT_ERRORS);
  67
  68        stats->rx_packets = readq(mem + NFP_MAC_STATS_RX_FRAMES_RECEIVED_OK);
  69        stats->rx_bytes = readq(mem + NFP_MAC_STATS_RX_IN_OCTETS);
  70        stats->rx_dropped = readq(mem + NFP_MAC_STATS_RX_IN_ERRORS);
  71}
  72
  73static void
  74nfp_repr_vnic_get_stats64(struct nfp_port *port,
  75                          struct rtnl_link_stats64 *stats)
  76{
  77        /* TX and RX stats are flipped as we are returning the stats as seen
  78         * at the switch port corresponding to the VF.
  79         */
  80        stats->tx_packets = readq(port->vnic + NFP_NET_CFG_STATS_RX_FRAMES);
  81        stats->tx_bytes = readq(port->vnic + NFP_NET_CFG_STATS_RX_OCTETS);
  82        stats->tx_dropped = readq(port->vnic + NFP_NET_CFG_STATS_RX_DISCARDS);
  83
  84        stats->rx_packets = readq(port->vnic + NFP_NET_CFG_STATS_TX_FRAMES);
  85        stats->rx_bytes = readq(port->vnic + NFP_NET_CFG_STATS_TX_OCTETS);
  86        stats->rx_dropped = readq(port->vnic + NFP_NET_CFG_STATS_TX_DISCARDS);
  87}
  88
  89static void
  90nfp_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
  91{
  92        struct nfp_repr *repr = netdev_priv(netdev);
  93
  94        if (WARN_ON(!repr->port))
  95                return;
  96
  97        switch (repr->port->type) {
  98        case NFP_PORT_PHYS_PORT:
  99                if (!__nfp_port_get_eth_port(repr->port))
 100                        break;
 101                nfp_repr_phy_port_get_stats64(repr->port, stats);
 102                break;
 103        case NFP_PORT_PF_PORT:
 104        case NFP_PORT_VF_PORT:
 105                nfp_repr_vnic_get_stats64(repr->port, stats);
 106        default:
 107                break;
 108        }
 109}
 110
 111static bool
 112nfp_repr_has_offload_stats(const struct net_device *dev, int attr_id)
 113{
 114        switch (attr_id) {
 115        case IFLA_OFFLOAD_XSTATS_CPU_HIT:
 116                return true;
 117        }
 118
 119        return false;
 120}
 121
 122static int
 123nfp_repr_get_host_stats64(const struct net_device *netdev,
 124                          struct rtnl_link_stats64 *stats)
 125{
 126        struct nfp_repr *repr = netdev_priv(netdev);
 127        int i;
 128
 129        for_each_possible_cpu(i) {
 130                u64 tbytes, tpkts, tdrops, rbytes, rpkts;
 131                struct nfp_repr_pcpu_stats *repr_stats;
 132                unsigned int start;
 133
 134                repr_stats = per_cpu_ptr(repr->stats, i);
 135                do {
 136                        start = u64_stats_fetch_begin_irq(&repr_stats->syncp);
 137                        tbytes = repr_stats->tx_bytes;
 138                        tpkts = repr_stats->tx_packets;
 139                        tdrops = repr_stats->tx_drops;
 140                        rbytes = repr_stats->rx_bytes;
 141                        rpkts = repr_stats->rx_packets;
 142                } while (u64_stats_fetch_retry_irq(&repr_stats->syncp, start));
 143
 144                stats->tx_bytes += tbytes;
 145                stats->tx_packets += tpkts;
 146                stats->tx_dropped += tdrops;
 147                stats->rx_bytes += rbytes;
 148                stats->rx_packets += rpkts;
 149        }
 150
 151        return 0;
 152}
 153
 154static int
 155nfp_repr_get_offload_stats(int attr_id, const struct net_device *dev,
 156                           void *stats)
 157{
 158        switch (attr_id) {
 159        case IFLA_OFFLOAD_XSTATS_CPU_HIT:
 160                return nfp_repr_get_host_stats64(dev, stats);
 161        }
 162
 163        return -EINVAL;
 164}
 165
 166static int nfp_repr_change_mtu(struct net_device *netdev, int new_mtu)
 167{
 168        struct nfp_repr *repr = netdev_priv(netdev);
 169        int err;
 170
 171        err = nfp_app_check_mtu(repr->app, netdev, new_mtu);
 172        if (err)
 173                return err;
 174
 175        err = nfp_app_repr_change_mtu(repr->app, netdev, new_mtu);
 176        if (err)
 177                return err;
 178
 179        netdev->mtu = new_mtu;
 180
 181        return 0;
 182}
 183
 184static netdev_tx_t nfp_repr_xmit(struct sk_buff *skb, struct net_device *netdev)
 185{
 186        struct nfp_repr *repr = netdev_priv(netdev);
 187        unsigned int len = skb->len;
 188        int ret;
 189
 190        skb_dst_drop(skb);
 191        dst_hold((struct dst_entry *)repr->dst);
 192        skb_dst_set(skb, (struct dst_entry *)repr->dst);
 193        skb->dev = repr->dst->u.port_info.lower_dev;
 194
 195        ret = dev_queue_xmit(skb);
 196        nfp_repr_inc_tx_stats(netdev, len, ret);
 197
 198        return NETDEV_TX_OK;
 199}
 200
 201static int nfp_repr_stop(struct net_device *netdev)
 202{
 203        struct nfp_repr *repr = netdev_priv(netdev);
 204        int err;
 205
 206        err = nfp_app_repr_stop(repr->app, repr);
 207        if (err)
 208                return err;
 209
 210        nfp_port_configure(netdev, false);
 211        return 0;
 212}
 213
 214static int nfp_repr_open(struct net_device *netdev)
 215{
 216        struct nfp_repr *repr = netdev_priv(netdev);
 217        int err;
 218
 219        err = nfp_port_configure(netdev, true);
 220        if (err)
 221                return err;
 222
 223        err = nfp_app_repr_open(repr->app, repr);
 224        if (err)
 225                goto err_port_disable;
 226
 227        return 0;
 228
 229err_port_disable:
 230        nfp_port_configure(netdev, false);
 231        return err;
 232}
 233
 234static netdev_features_t
 235nfp_repr_fix_features(struct net_device *netdev, netdev_features_t features)
 236{
 237        struct nfp_repr *repr = netdev_priv(netdev);
 238        netdev_features_t old_features = features;
 239        netdev_features_t lower_features;
 240        struct net_device *lower_dev;
 241
 242        lower_dev = repr->dst->u.port_info.lower_dev;
 243
 244        lower_features = lower_dev->features;
 245        if (lower_features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM))
 246                lower_features |= NETIF_F_HW_CSUM;
 247
 248        features = netdev_intersect_features(features, lower_features);
 249        features |= old_features & (NETIF_F_SOFT_FEATURES | NETIF_F_HW_TC);
 250        features |= NETIF_F_LLTX;
 251
 252        return features;
 253}
 254
 255const struct net_device_ops nfp_repr_netdev_ops = {
 256        .ndo_init               = nfp_app_ndo_init,
 257        .ndo_uninit             = nfp_app_ndo_uninit,
 258        .ndo_open               = nfp_repr_open,
 259        .ndo_stop               = nfp_repr_stop,
 260        .ndo_start_xmit         = nfp_repr_xmit,
 261        .ndo_change_mtu         = nfp_repr_change_mtu,
 262        .ndo_get_stats64        = nfp_repr_get_stats64,
 263        .ndo_has_offload_stats  = nfp_repr_has_offload_stats,
 264        .ndo_get_offload_stats  = nfp_repr_get_offload_stats,
 265        .ndo_get_phys_port_name = nfp_port_get_phys_port_name,
 266        .ndo_setup_tc           = nfp_port_setup_tc,
 267        .ndo_set_vf_mac         = nfp_app_set_vf_mac,
 268        .ndo_set_vf_vlan        = nfp_app_set_vf_vlan,
 269        .ndo_set_vf_spoofchk    = nfp_app_set_vf_spoofchk,
 270        .ndo_set_vf_trust       = nfp_app_set_vf_trust,
 271        .ndo_get_vf_config      = nfp_app_get_vf_config,
 272        .ndo_set_vf_link_state  = nfp_app_set_vf_link_state,
 273        .ndo_fix_features       = nfp_repr_fix_features,
 274        .ndo_set_features       = nfp_port_set_features,
 275        .ndo_set_mac_address    = eth_mac_addr,
 276        .ndo_get_port_parent_id = nfp_port_get_port_parent_id,
 277        .ndo_get_devlink_port   = nfp_devlink_get_devlink_port,
 278};
 279
 280void
 281nfp_repr_transfer_features(struct net_device *netdev, struct net_device *lower)
 282{
 283        struct nfp_repr *repr = netdev_priv(netdev);
 284
 285        if (repr->dst->u.port_info.lower_dev != lower)
 286                return;
 287
 288        netdev->gso_max_size = lower->gso_max_size;
 289        netdev->gso_max_segs = lower->gso_max_segs;
 290
 291        netdev_update_features(netdev);
 292}
 293
 294static void nfp_repr_clean(struct nfp_repr *repr)
 295{
 296        unregister_netdev(repr->netdev);
 297        nfp_app_repr_clean(repr->app, repr->netdev);
 298        dst_release((struct dst_entry *)repr->dst);
 299        nfp_port_free(repr->port);
 300}
 301
 302static struct lock_class_key nfp_repr_netdev_xmit_lock_key;
 303
 304static void nfp_repr_set_lockdep_class_one(struct net_device *dev,
 305                                           struct netdev_queue *txq,
 306                                           void *_unused)
 307{
 308        lockdep_set_class(&txq->_xmit_lock, &nfp_repr_netdev_xmit_lock_key);
 309}
 310
 311static void nfp_repr_set_lockdep_class(struct net_device *dev)
 312{
 313        netdev_for_each_tx_queue(dev, nfp_repr_set_lockdep_class_one, NULL);
 314}
 315
 316int nfp_repr_init(struct nfp_app *app, struct net_device *netdev,
 317                  u32 cmsg_port_id, struct nfp_port *port,
 318                  struct net_device *pf_netdev)
 319{
 320        struct nfp_repr *repr = netdev_priv(netdev);
 321        struct nfp_net *nn = netdev_priv(pf_netdev);
 322        u32 repr_cap = nn->tlv_caps.repr_cap;
 323        int err;
 324
 325        nfp_repr_set_lockdep_class(netdev);
 326
 327        repr->port = port;
 328        repr->dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, GFP_KERNEL);
 329        if (!repr->dst)
 330                return -ENOMEM;
 331        repr->dst->u.port_info.port_id = cmsg_port_id;
 332        repr->dst->u.port_info.lower_dev = pf_netdev;
 333
 334        netdev->netdev_ops = &nfp_repr_netdev_ops;
 335        netdev->ethtool_ops = &nfp_port_ethtool_ops;
 336
 337        netdev->max_mtu = pf_netdev->max_mtu;
 338
 339        /* Set features the lower device can support with representors */
 340        if (repr_cap & NFP_NET_CFG_CTRL_LIVE_ADDR)
 341                netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
 342
 343        netdev->hw_features = NETIF_F_HIGHDMA;
 344        if (repr_cap & NFP_NET_CFG_CTRL_RXCSUM_ANY)
 345                netdev->hw_features |= NETIF_F_RXCSUM;
 346        if (repr_cap & NFP_NET_CFG_CTRL_TXCSUM)
 347                netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
 348        if (repr_cap & NFP_NET_CFG_CTRL_GATHER)
 349                netdev->hw_features |= NETIF_F_SG;
 350        if ((repr_cap & NFP_NET_CFG_CTRL_LSO && nn->fw_ver.major > 2) ||
 351            repr_cap & NFP_NET_CFG_CTRL_LSO2)
 352                netdev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6;
 353        if (repr_cap & NFP_NET_CFG_CTRL_RSS_ANY)
 354                netdev->hw_features |= NETIF_F_RXHASH;
 355        if (repr_cap & NFP_NET_CFG_CTRL_VXLAN) {
 356                if (repr_cap & NFP_NET_CFG_CTRL_LSO)
 357                        netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
 358        }
 359        if (repr_cap & NFP_NET_CFG_CTRL_NVGRE) {
 360                if (repr_cap & NFP_NET_CFG_CTRL_LSO)
 361                        netdev->hw_features |= NETIF_F_GSO_GRE;
 362        }
 363        if (repr_cap & (NFP_NET_CFG_CTRL_VXLAN | NFP_NET_CFG_CTRL_NVGRE))
 364                netdev->hw_enc_features = netdev->hw_features;
 365
 366        netdev->vlan_features = netdev->hw_features;
 367
 368        if (repr_cap & NFP_NET_CFG_CTRL_RXVLAN)
 369                netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
 370        if (repr_cap & NFP_NET_CFG_CTRL_TXVLAN) {
 371                if (repr_cap & NFP_NET_CFG_CTRL_LSO2)
 372                        netdev_warn(netdev, "Device advertises both TSO2 and TXVLAN. Refusing to enable TXVLAN.\n");
 373                else
 374                        netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX;
 375        }
 376        if (repr_cap & NFP_NET_CFG_CTRL_CTAG_FILTER)
 377                netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 378
 379        netdev->features = netdev->hw_features;
 380
 381        /* Advertise but disable TSO by default. */
 382        netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
 383        netdev->gso_max_segs = NFP_NET_LSO_MAX_SEGS;
 384
 385        netdev->priv_flags |= IFF_NO_QUEUE | IFF_DISABLE_NETPOLL;
 386        netdev->features |= NETIF_F_LLTX;
 387
 388        if (nfp_app_has_tc(app)) {
 389                netdev->features |= NETIF_F_HW_TC;
 390                netdev->hw_features |= NETIF_F_HW_TC;
 391        }
 392
 393        err = nfp_app_repr_init(app, netdev);
 394        if (err)
 395                goto err_clean;
 396
 397        err = register_netdev(netdev);
 398        if (err)
 399                goto err_repr_clean;
 400
 401        return 0;
 402
 403err_repr_clean:
 404        nfp_app_repr_clean(app, netdev);
 405err_clean:
 406        dst_release((struct dst_entry *)repr->dst);
 407        return err;
 408}
 409
 410static void __nfp_repr_free(struct nfp_repr *repr)
 411{
 412        free_percpu(repr->stats);
 413        free_netdev(repr->netdev);
 414}
 415
 416void nfp_repr_free(struct net_device *netdev)
 417{
 418        __nfp_repr_free(netdev_priv(netdev));
 419}
 420
 421struct net_device *
 422nfp_repr_alloc_mqs(struct nfp_app *app, unsigned int txqs, unsigned int rxqs)
 423{
 424        struct net_device *netdev;
 425        struct nfp_repr *repr;
 426
 427        netdev = alloc_etherdev_mqs(sizeof(*repr), txqs, rxqs);
 428        if (!netdev)
 429                return NULL;
 430
 431        netif_carrier_off(netdev);
 432
 433        repr = netdev_priv(netdev);
 434        repr->netdev = netdev;
 435        repr->app = app;
 436
 437        repr->stats = netdev_alloc_pcpu_stats(struct nfp_repr_pcpu_stats);
 438        if (!repr->stats)
 439                goto err_free_netdev;
 440
 441        return netdev;
 442
 443err_free_netdev:
 444        free_netdev(netdev);
 445        return NULL;
 446}
 447
 448void nfp_repr_clean_and_free(struct nfp_repr *repr)
 449{
 450        nfp_info(repr->app->cpp, "Destroying Representor(%s)\n",
 451                 repr->netdev->name);
 452        nfp_repr_clean(repr);
 453        __nfp_repr_free(repr);
 454}
 455
 456void nfp_reprs_clean_and_free(struct nfp_app *app, struct nfp_reprs *reprs)
 457{
 458        struct net_device *netdev;
 459        unsigned int i;
 460
 461        for (i = 0; i < reprs->num_reprs; i++) {
 462                netdev = nfp_repr_get_locked(app, reprs, i);
 463                if (netdev)
 464                        nfp_repr_clean_and_free(netdev_priv(netdev));
 465        }
 466
 467        kfree(reprs);
 468}
 469
 470void
 471nfp_reprs_clean_and_free_by_type(struct nfp_app *app, enum nfp_repr_type type)
 472{
 473        struct net_device *netdev;
 474        struct nfp_reprs *reprs;
 475        int i;
 476
 477        reprs = rcu_dereference_protected(app->reprs[type],
 478                                          lockdep_is_held(&app->pf->lock));
 479        if (!reprs)
 480                return;
 481
 482        /* Preclean must happen before we remove the reprs reference from the
 483         * app below.
 484         */
 485        for (i = 0; i < reprs->num_reprs; i++) {
 486                netdev = nfp_repr_get_locked(app, reprs, i);
 487                if (netdev)
 488                        nfp_app_repr_preclean(app, netdev);
 489        }
 490
 491        reprs = nfp_app_reprs_set(app, type, NULL);
 492
 493        synchronize_rcu();
 494        nfp_reprs_clean_and_free(app, reprs);
 495}
 496
 497struct nfp_reprs *nfp_reprs_alloc(unsigned int num_reprs)
 498{
 499        struct nfp_reprs *reprs;
 500
 501        reprs = kzalloc(sizeof(*reprs) +
 502                        num_reprs * sizeof(struct net_device *), GFP_KERNEL);
 503        if (!reprs)
 504                return NULL;
 505        reprs->num_reprs = num_reprs;
 506
 507        return reprs;
 508}
 509
 510int nfp_reprs_resync_phys_ports(struct nfp_app *app)
 511{
 512        struct net_device *netdev;
 513        struct nfp_reprs *reprs;
 514        struct nfp_repr *repr;
 515        int i;
 516
 517        reprs = nfp_reprs_get_locked(app, NFP_REPR_TYPE_PHYS_PORT);
 518        if (!reprs)
 519                return 0;
 520
 521        for (i = 0; i < reprs->num_reprs; i++) {
 522                netdev = nfp_repr_get_locked(app, reprs, i);
 523                if (!netdev)
 524                        continue;
 525
 526                repr = netdev_priv(netdev);
 527                if (repr->port->type != NFP_PORT_INVALID)
 528                        continue;
 529
 530                nfp_app_repr_preclean(app, netdev);
 531                rtnl_lock();
 532                rcu_assign_pointer(reprs->reprs[i], NULL);
 533                rtnl_unlock();
 534                synchronize_rcu();
 535                nfp_repr_clean(repr);
 536        }
 537
 538        return 0;
 539}
 540