root/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c

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

DEFINITIONS

This source file includes following definitions.
  1. nfp_eth_rate2speed
  2. nfp_eth_speed2rate
  3. nfp_eth_copy_mac_reverse
  4. nfp_eth_port_translate
  5. nfp_eth_calc_port_geometry
  6. nfp_eth_calc_port_type
  7. nfp_eth_read_ports
  8. __nfp_eth_read_ports
  9. nfp_eth_config_start
  10. nfp_eth_config_cleanup_end
  11. nfp_eth_config_commit_end
  12. nfp_eth_set_mod_enable
  13. nfp_eth_set_configured
  14. nfp_eth_set_bit_config
  15. __nfp_eth_set_aneg
  16. __nfp_eth_set_fec
  17. nfp_eth_set_fec
  18. __nfp_eth_set_speed
  19. __nfp_eth_set_split

   1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
   2 /* Copyright (C) 2015-2017 Netronome Systems, Inc. */
   3 
   4 /* Authors: David Brunecz <david.brunecz@netronome.com>
   5  *          Jakub Kicinski <jakub.kicinski@netronome.com>
   6  *          Jason Mcmullan <jason.mcmullan@netronome.com>
   7  */
   8 
   9 #include <linux/bitfield.h>
  10 #include <linux/ethtool.h>
  11 #include <linux/if_ether.h>
  12 #include <linux/kernel.h>
  13 #include <linux/module.h>
  14 
  15 #include "nfp.h"
  16 #include "nfp_nsp.h"
  17 #include "nfp6000/nfp6000.h"
  18 
  19 #define NSP_ETH_NBI_PORT_COUNT          24
  20 #define NSP_ETH_MAX_COUNT               (2 * NSP_ETH_NBI_PORT_COUNT)
  21 #define NSP_ETH_TABLE_SIZE              (NSP_ETH_MAX_COUNT *            \
  22                                          sizeof(union eth_table_entry))
  23 
  24 #define NSP_ETH_PORT_LANES              GENMASK_ULL(3, 0)
  25 #define NSP_ETH_PORT_INDEX              GENMASK_ULL(15, 8)
  26 #define NSP_ETH_PORT_LABEL              GENMASK_ULL(53, 48)
  27 #define NSP_ETH_PORT_PHYLABEL           GENMASK_ULL(59, 54)
  28 #define NSP_ETH_PORT_FEC_SUPP_BASER     BIT_ULL(60)
  29 #define NSP_ETH_PORT_FEC_SUPP_RS        BIT_ULL(61)
  30 
  31 #define NSP_ETH_PORT_LANES_MASK         cpu_to_le64(NSP_ETH_PORT_LANES)
  32 
  33 #define NSP_ETH_STATE_CONFIGURED        BIT_ULL(0)
  34 #define NSP_ETH_STATE_ENABLED           BIT_ULL(1)
  35 #define NSP_ETH_STATE_TX_ENABLED        BIT_ULL(2)
  36 #define NSP_ETH_STATE_RX_ENABLED        BIT_ULL(3)
  37 #define NSP_ETH_STATE_RATE              GENMASK_ULL(11, 8)
  38 #define NSP_ETH_STATE_INTERFACE         GENMASK_ULL(19, 12)
  39 #define NSP_ETH_STATE_MEDIA             GENMASK_ULL(21, 20)
  40 #define NSP_ETH_STATE_OVRD_CHNG         BIT_ULL(22)
  41 #define NSP_ETH_STATE_ANEG              GENMASK_ULL(25, 23)
  42 #define NSP_ETH_STATE_FEC               GENMASK_ULL(27, 26)
  43 
  44 #define NSP_ETH_CTRL_CONFIGURED         BIT_ULL(0)
  45 #define NSP_ETH_CTRL_ENABLED            BIT_ULL(1)
  46 #define NSP_ETH_CTRL_TX_ENABLED         BIT_ULL(2)
  47 #define NSP_ETH_CTRL_RX_ENABLED         BIT_ULL(3)
  48 #define NSP_ETH_CTRL_SET_RATE           BIT_ULL(4)
  49 #define NSP_ETH_CTRL_SET_LANES          BIT_ULL(5)
  50 #define NSP_ETH_CTRL_SET_ANEG           BIT_ULL(6)
  51 #define NSP_ETH_CTRL_SET_FEC            BIT_ULL(7)
  52 
  53 enum nfp_eth_raw {
  54         NSP_ETH_RAW_PORT = 0,
  55         NSP_ETH_RAW_STATE,
  56         NSP_ETH_RAW_MAC,
  57         NSP_ETH_RAW_CONTROL,
  58 
  59         NSP_ETH_NUM_RAW
  60 };
  61 
  62 enum nfp_eth_rate {
  63         RATE_INVALID = 0,
  64         RATE_10M,
  65         RATE_100M,
  66         RATE_1G,
  67         RATE_10G,
  68         RATE_25G,
  69 };
  70 
  71 union eth_table_entry {
  72         struct {
  73                 __le64 port;
  74                 __le64 state;
  75                 u8 mac_addr[6];
  76                 u8 resv[2];
  77                 __le64 control;
  78         };
  79         __le64 raw[NSP_ETH_NUM_RAW];
  80 };
  81 
  82 static const struct {
  83         enum nfp_eth_rate rate;
  84         unsigned int speed;
  85 } nsp_eth_rate_tbl[] = {
  86         { RATE_INVALID, 0, },
  87         { RATE_10M,     SPEED_10, },
  88         { RATE_100M,    SPEED_100, },
  89         { RATE_1G,      SPEED_1000, },
  90         { RATE_10G,     SPEED_10000, },
  91         { RATE_25G,     SPEED_25000, },
  92 };
  93 
  94 static unsigned int nfp_eth_rate2speed(enum nfp_eth_rate rate)
  95 {
  96         int i;
  97 
  98         for (i = 0; i < ARRAY_SIZE(nsp_eth_rate_tbl); i++)
  99                 if (nsp_eth_rate_tbl[i].rate == rate)
 100                         return nsp_eth_rate_tbl[i].speed;
 101 
 102         return 0;
 103 }
 104 
 105 static unsigned int nfp_eth_speed2rate(unsigned int speed)
 106 {
 107         int i;
 108 
 109         for (i = 0; i < ARRAY_SIZE(nsp_eth_rate_tbl); i++)
 110                 if (nsp_eth_rate_tbl[i].speed == speed)
 111                         return nsp_eth_rate_tbl[i].rate;
 112 
 113         return RATE_INVALID;
 114 }
 115 
 116 static void nfp_eth_copy_mac_reverse(u8 *dst, const u8 *src)
 117 {
 118         int i;
 119 
 120         for (i = 0; i < ETH_ALEN; i++)
 121                 dst[ETH_ALEN - i - 1] = src[i];
 122 }
 123 
 124 static void
 125 nfp_eth_port_translate(struct nfp_nsp *nsp, const union eth_table_entry *src,
 126                        unsigned int index, struct nfp_eth_table_port *dst)
 127 {
 128         unsigned int rate;
 129         unsigned int fec;
 130         u64 port, state;
 131 
 132         port = le64_to_cpu(src->port);
 133         state = le64_to_cpu(src->state);
 134 
 135         dst->eth_index = FIELD_GET(NSP_ETH_PORT_INDEX, port);
 136         dst->index = index;
 137         dst->nbi = index / NSP_ETH_NBI_PORT_COUNT;
 138         dst->base = index % NSP_ETH_NBI_PORT_COUNT;
 139         dst->lanes = FIELD_GET(NSP_ETH_PORT_LANES, port);
 140 
 141         dst->enabled = FIELD_GET(NSP_ETH_STATE_ENABLED, state);
 142         dst->tx_enabled = FIELD_GET(NSP_ETH_STATE_TX_ENABLED, state);
 143         dst->rx_enabled = FIELD_GET(NSP_ETH_STATE_RX_ENABLED, state);
 144 
 145         rate = nfp_eth_rate2speed(FIELD_GET(NSP_ETH_STATE_RATE, state));
 146         dst->speed = dst->lanes * rate;
 147 
 148         dst->interface = FIELD_GET(NSP_ETH_STATE_INTERFACE, state);
 149         dst->media = FIELD_GET(NSP_ETH_STATE_MEDIA, state);
 150 
 151         nfp_eth_copy_mac_reverse(dst->mac_addr, src->mac_addr);
 152 
 153         dst->label_port = FIELD_GET(NSP_ETH_PORT_PHYLABEL, port);
 154         dst->label_subport = FIELD_GET(NSP_ETH_PORT_LABEL, port);
 155 
 156         if (nfp_nsp_get_abi_ver_minor(nsp) < 17)
 157                 return;
 158 
 159         dst->override_changed = FIELD_GET(NSP_ETH_STATE_OVRD_CHNG, state);
 160         dst->aneg = FIELD_GET(NSP_ETH_STATE_ANEG, state);
 161 
 162         if (nfp_nsp_get_abi_ver_minor(nsp) < 22)
 163                 return;
 164 
 165         fec = FIELD_GET(NSP_ETH_PORT_FEC_SUPP_BASER, port);
 166         dst->fec_modes_supported |= fec << NFP_FEC_BASER_BIT;
 167         fec = FIELD_GET(NSP_ETH_PORT_FEC_SUPP_RS, port);
 168         dst->fec_modes_supported |= fec << NFP_FEC_REED_SOLOMON_BIT;
 169         if (dst->fec_modes_supported)
 170                 dst->fec_modes_supported |= NFP_FEC_AUTO | NFP_FEC_DISABLED;
 171 
 172         dst->fec = 1 << FIELD_GET(NSP_ETH_STATE_FEC, state);
 173 }
 174 
 175 static void
 176 nfp_eth_calc_port_geometry(struct nfp_cpp *cpp, struct nfp_eth_table *table)
 177 {
 178         unsigned int i, j;
 179 
 180         for (i = 0; i < table->count; i++) {
 181                 table->max_index = max(table->max_index, table->ports[i].index);
 182 
 183                 for (j = 0; j < table->count; j++) {
 184                         if (table->ports[i].label_port !=
 185                             table->ports[j].label_port)
 186                                 continue;
 187                         table->ports[i].port_lanes += table->ports[j].lanes;
 188 
 189                         if (i == j)
 190                                 continue;
 191                         if (table->ports[i].label_subport ==
 192                             table->ports[j].label_subport)
 193                                 nfp_warn(cpp,
 194                                          "Port %d subport %d is a duplicate\n",
 195                                          table->ports[i].label_port,
 196                                          table->ports[i].label_subport);
 197 
 198                         table->ports[i].is_split = true;
 199                 }
 200         }
 201 }
 202 
 203 static void
 204 nfp_eth_calc_port_type(struct nfp_cpp *cpp, struct nfp_eth_table_port *entry)
 205 {
 206         if (entry->interface == NFP_INTERFACE_NONE) {
 207                 entry->port_type = PORT_NONE;
 208                 return;
 209         } else if (entry->interface == NFP_INTERFACE_RJ45) {
 210                 entry->port_type = PORT_TP;
 211                 return;
 212         }
 213 
 214         if (entry->media == NFP_MEDIA_FIBRE)
 215                 entry->port_type = PORT_FIBRE;
 216         else
 217                 entry->port_type = PORT_DA;
 218 }
 219 
 220 /**
 221  * nfp_eth_read_ports() - retrieve port information
 222  * @cpp:        NFP CPP handle
 223  *
 224  * Read the port information from the device.  Returned structure should
 225  * be freed with kfree() once no longer needed.
 226  *
 227  * Return: populated ETH table or NULL on error.
 228  */
 229 struct nfp_eth_table *nfp_eth_read_ports(struct nfp_cpp *cpp)
 230 {
 231         struct nfp_eth_table *ret;
 232         struct nfp_nsp *nsp;
 233 
 234         nsp = nfp_nsp_open(cpp);
 235         if (IS_ERR(nsp))
 236                 return NULL;
 237 
 238         ret = __nfp_eth_read_ports(cpp, nsp);
 239         nfp_nsp_close(nsp);
 240 
 241         return ret;
 242 }
 243 
 244 struct nfp_eth_table *
 245 __nfp_eth_read_ports(struct nfp_cpp *cpp, struct nfp_nsp *nsp)
 246 {
 247         union eth_table_entry *entries;
 248         struct nfp_eth_table *table;
 249         int i, j, ret, cnt = 0;
 250 
 251         entries = kzalloc(NSP_ETH_TABLE_SIZE, GFP_KERNEL);
 252         if (!entries)
 253                 return NULL;
 254 
 255         ret = nfp_nsp_read_eth_table(nsp, entries, NSP_ETH_TABLE_SIZE);
 256         if (ret < 0) {
 257                 nfp_err(cpp, "reading port table failed %d\n", ret);
 258                 goto err;
 259         }
 260 
 261         for (i = 0; i < NSP_ETH_MAX_COUNT; i++)
 262                 if (entries[i].port & NSP_ETH_PORT_LANES_MASK)
 263                         cnt++;
 264 
 265         /* Some versions of flash will give us 0 instead of port count.
 266          * For those that give a port count, verify it against the value
 267          * calculated above.
 268          */
 269         if (ret && ret != cnt) {
 270                 nfp_err(cpp, "table entry count reported (%d) does not match entries present (%d)\n",
 271                         ret, cnt);
 272                 goto err;
 273         }
 274 
 275         table = kzalloc(struct_size(table, ports, cnt), GFP_KERNEL);
 276         if (!table)
 277                 goto err;
 278 
 279         table->count = cnt;
 280         for (i = 0, j = 0; i < NSP_ETH_MAX_COUNT; i++)
 281                 if (entries[i].port & NSP_ETH_PORT_LANES_MASK)
 282                         nfp_eth_port_translate(nsp, &entries[i], i,
 283                                                &table->ports[j++]);
 284 
 285         nfp_eth_calc_port_geometry(cpp, table);
 286         for (i = 0; i < table->count; i++)
 287                 nfp_eth_calc_port_type(cpp, &table->ports[i]);
 288 
 289         kfree(entries);
 290 
 291         return table;
 292 
 293 err:
 294         kfree(entries);
 295         return NULL;
 296 }
 297 
 298 struct nfp_nsp *nfp_eth_config_start(struct nfp_cpp *cpp, unsigned int idx)
 299 {
 300         union eth_table_entry *entries;
 301         struct nfp_nsp *nsp;
 302         int ret;
 303 
 304         entries = kzalloc(NSP_ETH_TABLE_SIZE, GFP_KERNEL);
 305         if (!entries)
 306                 return ERR_PTR(-ENOMEM);
 307 
 308         nsp = nfp_nsp_open(cpp);
 309         if (IS_ERR(nsp)) {
 310                 kfree(entries);
 311                 return nsp;
 312         }
 313 
 314         ret = nfp_nsp_read_eth_table(nsp, entries, NSP_ETH_TABLE_SIZE);
 315         if (ret < 0) {
 316                 nfp_err(cpp, "reading port table failed %d\n", ret);
 317                 goto err;
 318         }
 319 
 320         if (!(entries[idx].port & NSP_ETH_PORT_LANES_MASK)) {
 321                 nfp_warn(cpp, "trying to set port state on disabled port %d\n",
 322                          idx);
 323                 goto err;
 324         }
 325 
 326         nfp_nsp_config_set_state(nsp, entries, idx);
 327         return nsp;
 328 
 329 err:
 330         nfp_nsp_close(nsp);
 331         kfree(entries);
 332         return ERR_PTR(-EIO);
 333 }
 334 
 335 void nfp_eth_config_cleanup_end(struct nfp_nsp *nsp)
 336 {
 337         union eth_table_entry *entries = nfp_nsp_config_entries(nsp);
 338 
 339         nfp_nsp_config_set_modified(nsp, false);
 340         nfp_nsp_config_clear_state(nsp);
 341         nfp_nsp_close(nsp);
 342         kfree(entries);
 343 }
 344 
 345 /**
 346  * nfp_eth_config_commit_end() - perform recorded configuration changes
 347  * @nsp:        NFP NSP handle returned from nfp_eth_config_start()
 348  *
 349  * Perform the configuration which was requested with __nfp_eth_set_*()
 350  * helpers and recorded in @nsp state.  If device was already configured
 351  * as requested or no __nfp_eth_set_*() operations were made no NSP command
 352  * will be performed.
 353  *
 354  * Return:
 355  * 0 - configuration successful;
 356  * 1 - no changes were needed;
 357  * -ERRNO - configuration failed.
 358  */
 359 int nfp_eth_config_commit_end(struct nfp_nsp *nsp)
 360 {
 361         union eth_table_entry *entries = nfp_nsp_config_entries(nsp);
 362         int ret = 1;
 363 
 364         if (nfp_nsp_config_modified(nsp)) {
 365                 ret = nfp_nsp_write_eth_table(nsp, entries, NSP_ETH_TABLE_SIZE);
 366                 ret = ret < 0 ? ret : 0;
 367         }
 368 
 369         nfp_eth_config_cleanup_end(nsp);
 370 
 371         return ret;
 372 }
 373 
 374 /**
 375  * nfp_eth_set_mod_enable() - set PHY module enable control bit
 376  * @cpp:        NFP CPP handle
 377  * @idx:        NFP chip-wide port index
 378  * @enable:     Desired state
 379  *
 380  * Enable or disable PHY module (this usually means setting the TX lanes
 381  * disable bits).
 382  *
 383  * Return:
 384  * 0 - configuration successful;
 385  * 1 - no changes were needed;
 386  * -ERRNO - configuration failed.
 387  */
 388 int nfp_eth_set_mod_enable(struct nfp_cpp *cpp, unsigned int idx, bool enable)
 389 {
 390         union eth_table_entry *entries;
 391         struct nfp_nsp *nsp;
 392         u64 reg;
 393 
 394         nsp = nfp_eth_config_start(cpp, idx);
 395         if (IS_ERR(nsp))
 396                 return PTR_ERR(nsp);
 397 
 398         entries = nfp_nsp_config_entries(nsp);
 399 
 400         /* Check if we are already in requested state */
 401         reg = le64_to_cpu(entries[idx].state);
 402         if (enable != FIELD_GET(NSP_ETH_CTRL_ENABLED, reg)) {
 403                 reg = le64_to_cpu(entries[idx].control);
 404                 reg &= ~NSP_ETH_CTRL_ENABLED;
 405                 reg |= FIELD_PREP(NSP_ETH_CTRL_ENABLED, enable);
 406                 entries[idx].control = cpu_to_le64(reg);
 407 
 408                 nfp_nsp_config_set_modified(nsp, true);
 409         }
 410 
 411         return nfp_eth_config_commit_end(nsp);
 412 }
 413 
 414 /**
 415  * nfp_eth_set_configured() - set PHY module configured control bit
 416  * @cpp:        NFP CPP handle
 417  * @idx:        NFP chip-wide port index
 418  * @configed:   Desired state
 419  *
 420  * Set the ifup/ifdown state on the PHY.
 421  *
 422  * Return:
 423  * 0 - configuration successful;
 424  * 1 - no changes were needed;
 425  * -ERRNO - configuration failed.
 426  */
 427 int nfp_eth_set_configured(struct nfp_cpp *cpp, unsigned int idx, bool configed)
 428 {
 429         union eth_table_entry *entries;
 430         struct nfp_nsp *nsp;
 431         u64 reg;
 432 
 433         nsp = nfp_eth_config_start(cpp, idx);
 434         if (IS_ERR(nsp))
 435                 return PTR_ERR(nsp);
 436 
 437         /* Older ABI versions did support this feature, however this has only
 438          * been reliable since ABI 20.
 439          */
 440         if (nfp_nsp_get_abi_ver_minor(nsp) < 20) {
 441                 nfp_eth_config_cleanup_end(nsp);
 442                 return -EOPNOTSUPP;
 443         }
 444 
 445         entries = nfp_nsp_config_entries(nsp);
 446 
 447         /* Check if we are already in requested state */
 448         reg = le64_to_cpu(entries[idx].state);
 449         if (configed != FIELD_GET(NSP_ETH_STATE_CONFIGURED, reg)) {
 450                 reg = le64_to_cpu(entries[idx].control);
 451                 reg &= ~NSP_ETH_CTRL_CONFIGURED;
 452                 reg |= FIELD_PREP(NSP_ETH_CTRL_CONFIGURED, configed);
 453                 entries[idx].control = cpu_to_le64(reg);
 454 
 455                 nfp_nsp_config_set_modified(nsp, true);
 456         }
 457 
 458         return nfp_eth_config_commit_end(nsp);
 459 }
 460 
 461 static int
 462 nfp_eth_set_bit_config(struct nfp_nsp *nsp, unsigned int raw_idx,
 463                        const u64 mask, const unsigned int shift,
 464                        unsigned int val, const u64 ctrl_bit)
 465 {
 466         union eth_table_entry *entries = nfp_nsp_config_entries(nsp);
 467         unsigned int idx = nfp_nsp_config_idx(nsp);
 468         u64 reg;
 469 
 470         /* Note: set features were added in ABI 0.14 but the error
 471          *       codes were initially not populated correctly.
 472          */
 473         if (nfp_nsp_get_abi_ver_minor(nsp) < 17) {
 474                 nfp_err(nfp_nsp_cpp(nsp),
 475                         "set operations not supported, please update flash\n");
 476                 return -EOPNOTSUPP;
 477         }
 478 
 479         /* Check if we are already in requested state */
 480         reg = le64_to_cpu(entries[idx].raw[raw_idx]);
 481         if (val == (reg & mask) >> shift)
 482                 return 0;
 483 
 484         reg &= ~mask;
 485         reg |= (val << shift) & mask;
 486         entries[idx].raw[raw_idx] = cpu_to_le64(reg);
 487 
 488         entries[idx].control |= cpu_to_le64(ctrl_bit);
 489 
 490         nfp_nsp_config_set_modified(nsp, true);
 491 
 492         return 0;
 493 }
 494 
 495 #define NFP_ETH_SET_BIT_CONFIG(nsp, raw_idx, mask, val, ctrl_bit)       \
 496         ({                                                              \
 497                 __BF_FIELD_CHECK(mask, 0ULL, val, "NFP_ETH_SET_BIT_CONFIG: "); \
 498                 nfp_eth_set_bit_config(nsp, raw_idx, mask, __bf_shf(mask), \
 499                                        val, ctrl_bit);                  \
 500         })
 501 
 502 /**
 503  * __nfp_eth_set_aneg() - set PHY autonegotiation control bit
 504  * @nsp:        NFP NSP handle returned from nfp_eth_config_start()
 505  * @mode:       Desired autonegotiation mode
 506  *
 507  * Allow/disallow PHY module to advertise/perform autonegotiation.
 508  * Will write to hwinfo overrides in the flash (persistent config).
 509  *
 510  * Return: 0 or -ERRNO.
 511  */
 512 int __nfp_eth_set_aneg(struct nfp_nsp *nsp, enum nfp_eth_aneg mode)
 513 {
 514         return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE,
 515                                       NSP_ETH_STATE_ANEG, mode,
 516                                       NSP_ETH_CTRL_SET_ANEG);
 517 }
 518 
 519 /**
 520  * __nfp_eth_set_fec() - set PHY forward error correction control bit
 521  * @nsp:        NFP NSP handle returned from nfp_eth_config_start()
 522  * @mode:       Desired fec mode
 523  *
 524  * Set the PHY module forward error correction mode.
 525  * Will write to hwinfo overrides in the flash (persistent config).
 526  *
 527  * Return: 0 or -ERRNO.
 528  */
 529 static int __nfp_eth_set_fec(struct nfp_nsp *nsp, enum nfp_eth_fec mode)
 530 {
 531         return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE,
 532                                       NSP_ETH_STATE_FEC, mode,
 533                                       NSP_ETH_CTRL_SET_FEC);
 534 }
 535 
 536 /**
 537  * nfp_eth_set_fec() - set PHY forward error correction control mode
 538  * @cpp:        NFP CPP handle
 539  * @idx:        NFP chip-wide port index
 540  * @mode:       Desired fec mode
 541  *
 542  * Return:
 543  * 0 - configuration successful;
 544  * 1 - no changes were needed;
 545  * -ERRNO - configuration failed.
 546  */
 547 int
 548 nfp_eth_set_fec(struct nfp_cpp *cpp, unsigned int idx, enum nfp_eth_fec mode)
 549 {
 550         struct nfp_nsp *nsp;
 551         int err;
 552 
 553         nsp = nfp_eth_config_start(cpp, idx);
 554         if (IS_ERR(nsp))
 555                 return PTR_ERR(nsp);
 556 
 557         err = __nfp_eth_set_fec(nsp, mode);
 558         if (err) {
 559                 nfp_eth_config_cleanup_end(nsp);
 560                 return err;
 561         }
 562 
 563         return nfp_eth_config_commit_end(nsp);
 564 }
 565 
 566 /**
 567  * __nfp_eth_set_speed() - set interface speed/rate
 568  * @nsp:        NFP NSP handle returned from nfp_eth_config_start()
 569  * @speed:      Desired speed (per lane)
 570  *
 571  * Set lane speed.  Provided @speed value should be subport speed divided
 572  * by number of lanes this subport is spanning (i.e. 10000 for 40G, 25000 for
 573  * 50G, etc.)
 574  * Will write to hwinfo overrides in the flash (persistent config).
 575  *
 576  * Return: 0 or -ERRNO.
 577  */
 578 int __nfp_eth_set_speed(struct nfp_nsp *nsp, unsigned int speed)
 579 {
 580         enum nfp_eth_rate rate;
 581 
 582         rate = nfp_eth_speed2rate(speed);
 583         if (rate == RATE_INVALID) {
 584                 nfp_warn(nfp_nsp_cpp(nsp),
 585                          "could not find matching lane rate for speed %u\n",
 586                          speed);
 587                 return -EINVAL;
 588         }
 589 
 590         return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE,
 591                                       NSP_ETH_STATE_RATE, rate,
 592                                       NSP_ETH_CTRL_SET_RATE);
 593 }
 594 
 595 /**
 596  * __nfp_eth_set_split() - set interface lane split
 597  * @nsp:        NFP NSP handle returned from nfp_eth_config_start()
 598  * @lanes:      Desired lanes per port
 599  *
 600  * Set number of lanes in the port.
 601  * Will write to hwinfo overrides in the flash (persistent config).
 602  *
 603  * Return: 0 or -ERRNO.
 604  */
 605 int __nfp_eth_set_split(struct nfp_nsp *nsp, unsigned int lanes)
 606 {
 607         return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_PORT, NSP_ETH_PORT_LANES,
 608                                       lanes, NSP_ETH_CTRL_SET_LANES);
 609 }

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