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