root/drivers/net/ethernet/netronome/nfp/nfp_port.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nfp_port_from_netdev
  2. nfp_port_get_port_parent_id
  3. nfp_port_setup_tc
  4. nfp_port_set_features
  5. nfp_port_from_id
  6. __nfp_port_get_eth_port
  7. nfp_port_get_eth_port
  8. nfp_port_get_phys_port_name
  9. nfp_port_configure
  10. nfp_port_init_phy_port
  11. nfp_port_alloc
  12. nfp_port_free

   1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
   2 /* Copyright (C) 2017-2018 Netronome Systems, Inc. */
   3 
   4 #include <linux/lockdep.h>
   5 #include <linux/netdevice.h>
   6 
   7 #include "nfpcore/nfp_cpp.h"
   8 #include "nfpcore/nfp_nsp.h"
   9 #include "nfp_app.h"
  10 #include "nfp_main.h"
  11 #include "nfp_net.h"
  12 #include "nfp_port.h"
  13 
  14 struct nfp_port *nfp_port_from_netdev(struct net_device *netdev)
  15 {
  16         if (nfp_netdev_is_nfp_net(netdev)) {
  17                 struct nfp_net *nn = netdev_priv(netdev);
  18 
  19                 return nn->port;
  20         }
  21 
  22         if (nfp_netdev_is_nfp_repr(netdev)) {
  23                 struct nfp_repr *repr = netdev_priv(netdev);
  24 
  25                 return repr->port;
  26         }
  27 
  28         WARN(1, "Unknown netdev type for nfp_port\n");
  29 
  30         return NULL;
  31 }
  32 
  33 int nfp_port_get_port_parent_id(struct net_device *netdev,
  34                                 struct netdev_phys_item_id *ppid)
  35 {
  36         struct nfp_port *port;
  37         const u8 *serial;
  38 
  39         port = nfp_port_from_netdev(netdev);
  40         if (!port)
  41                 return -EOPNOTSUPP;
  42 
  43         ppid->id_len = nfp_cpp_serial(port->app->cpp, &serial);
  44         memcpy(&ppid->id, serial, ppid->id_len);
  45 
  46         return 0;
  47 }
  48 
  49 int nfp_port_setup_tc(struct net_device *netdev, enum tc_setup_type type,
  50                       void *type_data)
  51 {
  52         struct nfp_port *port;
  53 
  54         port = nfp_port_from_netdev(netdev);
  55         if (!port)
  56                 return -EOPNOTSUPP;
  57 
  58         return nfp_app_setup_tc(port->app, netdev, type, type_data);
  59 }
  60 
  61 int nfp_port_set_features(struct net_device *netdev, netdev_features_t features)
  62 {
  63         struct nfp_port *port;
  64 
  65         port = nfp_port_from_netdev(netdev);
  66         if (!port)
  67                 return 0;
  68 
  69         if ((netdev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) &&
  70             port->tc_offload_cnt) {
  71                 netdev_err(netdev, "Cannot disable HW TC offload while offloads active\n");
  72                 return -EBUSY;
  73         }
  74 
  75         return 0;
  76 }
  77 
  78 struct nfp_port *
  79 nfp_port_from_id(struct nfp_pf *pf, enum nfp_port_type type, unsigned int id)
  80 {
  81         struct nfp_port *port;
  82 
  83         lockdep_assert_held(&pf->lock);
  84 
  85         if (type != NFP_PORT_PHYS_PORT)
  86                 return NULL;
  87 
  88         list_for_each_entry(port, &pf->ports, port_list)
  89                 if (port->eth_id == id)
  90                         return port;
  91 
  92         return NULL;
  93 }
  94 
  95 struct nfp_eth_table_port *__nfp_port_get_eth_port(struct nfp_port *port)
  96 {
  97         if (!port)
  98                 return NULL;
  99         if (port->type != NFP_PORT_PHYS_PORT)
 100                 return NULL;
 101 
 102         return port->eth_port;
 103 }
 104 
 105 struct nfp_eth_table_port *nfp_port_get_eth_port(struct nfp_port *port)
 106 {
 107         if (!__nfp_port_get_eth_port(port))
 108                 return NULL;
 109 
 110         if (test_bit(NFP_PORT_CHANGED, &port->flags))
 111                 if (nfp_net_refresh_eth_port(port))
 112                         return NULL;
 113 
 114         return __nfp_port_get_eth_port(port);
 115 }
 116 
 117 int
 118 nfp_port_get_phys_port_name(struct net_device *netdev, char *name, size_t len)
 119 {
 120         struct nfp_eth_table_port *eth_port;
 121         struct nfp_port *port;
 122         int n;
 123 
 124         port = nfp_port_from_netdev(netdev);
 125         if (!port)
 126                 return -EOPNOTSUPP;
 127 
 128         switch (port->type) {
 129         case NFP_PORT_PHYS_PORT:
 130                 eth_port = __nfp_port_get_eth_port(port);
 131                 if (!eth_port)
 132                         return -EOPNOTSUPP;
 133 
 134                 if (!eth_port->is_split)
 135                         n = snprintf(name, len, "p%d", eth_port->label_port);
 136                 else
 137                         n = snprintf(name, len, "p%ds%d", eth_port->label_port,
 138                                      eth_port->label_subport);
 139                 break;
 140         case NFP_PORT_PF_PORT:
 141                 if (!port->pf_split)
 142                         n = snprintf(name, len, "pf%d", port->pf_id);
 143                 else
 144                         n = snprintf(name, len, "pf%ds%d", port->pf_id,
 145                                      port->pf_split_id);
 146                 break;
 147         case NFP_PORT_VF_PORT:
 148                 n = snprintf(name, len, "pf%dvf%d", port->pf_id, port->vf_id);
 149                 break;
 150         default:
 151                 return -EOPNOTSUPP;
 152         }
 153 
 154         if (n >= len)
 155                 return -EINVAL;
 156 
 157         return 0;
 158 }
 159 
 160 /**
 161  * nfp_port_configure() - helper to set the interface configured bit
 162  * @netdev:     net_device instance
 163  * @configed:   Desired state
 164  *
 165  * Helper to set the ifup/ifdown state on the PHY only if there is a physical
 166  * interface associated with the netdev.
 167  *
 168  * Return:
 169  * 0 - configuration successful (or no change);
 170  * -ERRNO - configuration failed.
 171  */
 172 int nfp_port_configure(struct net_device *netdev, bool configed)
 173 {
 174         struct nfp_eth_table_port *eth_port;
 175         struct nfp_port *port;
 176         int err;
 177 
 178         port = nfp_port_from_netdev(netdev);
 179         eth_port = __nfp_port_get_eth_port(port);
 180         if (!eth_port)
 181                 return 0;
 182         if (port->eth_forced)
 183                 return 0;
 184 
 185         err = nfp_eth_set_configured(port->app->cpp, eth_port->index, configed);
 186         return err < 0 && err != -EOPNOTSUPP ? err : 0;
 187 }
 188 
 189 int nfp_port_init_phy_port(struct nfp_pf *pf, struct nfp_app *app,
 190                            struct nfp_port *port, unsigned int id)
 191 {
 192         /* Check if vNIC has external port associated and cfg is OK */
 193         if (!pf->eth_tbl || id >= pf->eth_tbl->count) {
 194                 nfp_err(app->cpp,
 195                         "NSP port entries don't match vNICs (no entry %d)\n",
 196                         id);
 197                 return -EINVAL;
 198         }
 199         if (pf->eth_tbl->ports[id].override_changed) {
 200                 nfp_warn(app->cpp,
 201                          "Config changed for port #%d, reboot required before port will be operational\n",
 202                          pf->eth_tbl->ports[id].index);
 203                 port->type = NFP_PORT_INVALID;
 204                 return 0;
 205         }
 206 
 207         port->eth_port = &pf->eth_tbl->ports[id];
 208         port->eth_id = pf->eth_tbl->ports[id].index;
 209         if (pf->mac_stats_mem)
 210                 port->eth_stats =
 211                         pf->mac_stats_mem + port->eth_id * NFP_MAC_STATS_SIZE;
 212 
 213         return 0;
 214 }
 215 
 216 struct nfp_port *
 217 nfp_port_alloc(struct nfp_app *app, enum nfp_port_type type,
 218                struct net_device *netdev)
 219 {
 220         struct nfp_port *port;
 221 
 222         port = kzalloc(sizeof(*port), GFP_KERNEL);
 223         if (!port)
 224                 return ERR_PTR(-ENOMEM);
 225 
 226         port->netdev = netdev;
 227         port->type = type;
 228         port->app = app;
 229 
 230         list_add_tail(&port->port_list, &app->pf->ports);
 231 
 232         return port;
 233 }
 234 
 235 void nfp_port_free(struct nfp_port *port)
 236 {
 237         if (!port)
 238                 return;
 239         list_del(&port->port_list);
 240         kfree(port);
 241 }

/* [<][>][^][v][top][bottom][index][help] */