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