1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2017 Intel Corporation 3 */ 4 5 #include <string.h> 6 7 #include <rte_mbuf.h> 8 #include <rte_malloc.h> 9 #include <rte_ethdev_driver.h> 10 #include <rte_tcp.h> 11 #include <rte_bus_vdev.h> 12 #include <rte_kvargs.h> 13 14 #include "rte_eth_bond.h" 15 #include "rte_eth_bond_private.h" 16 #include "rte_eth_bond_8023ad_private.h" 17 18 int 19 check_for_bonded_ethdev(const struct rte_eth_dev *eth_dev) 20 { 21 /* Check valid pointer */ 22 if (eth_dev->device->driver->name == NULL) 23 return -1; 24 25 /* return 0 if driver name matches */ 26 return eth_dev->device->driver->name != pmd_bond_drv.driver.name; 27 } 28 29 int 30 valid_bonded_port_id(uint16_t port_id) 31 { 32 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1); 33 return check_for_bonded_ethdev(&rte_eth_devices[port_id]); 34 } 35 36 int 37 check_for_master_bonded_ethdev(const struct rte_eth_dev *eth_dev) 38 { 39 int i; 40 struct bond_dev_private *internals; 41 42 if (check_for_bonded_ethdev(eth_dev) != 0) 43 return 0; 44 45 internals = eth_dev->data->dev_private; 46 47 /* Check if any of slave devices is a bonded device */ 48 for (i = 0; i < internals->slave_count; i++) 49 if (valid_bonded_port_id(internals->slaves[i].port_id) == 0) 50 return 1; 51 52 return 0; 53 } 54 55 int 56 valid_slave_port_id(uint16_t port_id, uint8_t mode) 57 { 58 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1); 59 60 /* Verify that port_id refers to a non bonded port */ 61 if (check_for_bonded_ethdev(&rte_eth_devices[port_id]) == 0 && 62 mode == BONDING_MODE_8023AD) { 63 RTE_BOND_LOG(ERR, "Cannot add slave to bonded device in 802.3ad" 64 " mode as slave is also a bonded device, only " 65 "physical devices can be support in this mode."); 66 return -1; 67 } 68 69 return 0; 70 } 71 72 void 73 activate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id) 74 { 75 struct bond_dev_private *internals = eth_dev->data->dev_private; 76 uint8_t active_count = internals->active_slave_count; 77 78 if (internals->mode == BONDING_MODE_8023AD) 79 bond_mode_8023ad_activate_slave(eth_dev, port_id); 80 81 if (internals->mode == BONDING_MODE_TLB 82 || internals->mode == BONDING_MODE_ALB) { 83 84 internals->tlb_slaves_order[active_count] = port_id; 85 } 86 87 RTE_ASSERT(internals->active_slave_count < 88 (RTE_DIM(internals->active_slaves) - 1)); 89 90 internals->active_slaves[internals->active_slave_count] = port_id; 91 internals->active_slave_count++; 92 93 if (internals->mode == BONDING_MODE_TLB) 94 bond_tlb_activate_slave(internals); 95 if (internals->mode == BONDING_MODE_ALB) 96 bond_mode_alb_client_list_upd(eth_dev); 97 } 98 99 void 100 deactivate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id) 101 { 102 uint16_t slave_pos; 103 struct bond_dev_private *internals = eth_dev->data->dev_private; 104 uint16_t active_count = internals->active_slave_count; 105 106 if (internals->mode == BONDING_MODE_8023AD) { 107 bond_mode_8023ad_stop(eth_dev); 108 bond_mode_8023ad_deactivate_slave(eth_dev, port_id); 109 } else if (internals->mode == BONDING_MODE_TLB 110 || internals->mode == BONDING_MODE_ALB) 111 bond_tlb_disable(internals); 112 113 slave_pos = find_slave_by_id(internals->active_slaves, active_count, 114 port_id); 115 116 /* If slave was not at the end of the list 117 * shift active slaves up active array list */ 118 if (slave_pos < active_count) { 119 active_count--; 120 memmove(internals->active_slaves + slave_pos, 121 internals->active_slaves + slave_pos + 1, 122 (active_count - slave_pos) * 123 sizeof(internals->active_slaves[0])); 124 } 125 126 RTE_ASSERT(active_count < RTE_DIM(internals->active_slaves)); 127 internals->active_slave_count = active_count; 128 129 if (eth_dev->data->dev_started) { 130 if (internals->mode == BONDING_MODE_8023AD) { 131 bond_mode_8023ad_start(eth_dev); 132 } else if (internals->mode == BONDING_MODE_TLB) { 133 bond_tlb_enable(internals); 134 } else if (internals->mode == BONDING_MODE_ALB) { 135 bond_tlb_enable(internals); 136 bond_mode_alb_client_list_upd(eth_dev); 137 } 138 } 139 } 140 141 int 142 rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id) 143 { 144 struct bond_dev_private *internals; 145 char devargs[52]; 146 uint16_t port_id; 147 int ret; 148 149 if (name == NULL) { 150 RTE_BOND_LOG(ERR, "Invalid name specified"); 151 return -EINVAL; 152 } 153 154 ret = snprintf(devargs, sizeof(devargs), 155 "driver=net_bonding,mode=%d,socket_id=%d", mode, socket_id); 156 if (ret < 0 || ret >= (int)sizeof(devargs)) 157 return -ENOMEM; 158 159 ret = rte_vdev_init(name, devargs); 160 if (ret) 161 return -ENOMEM; 162 163 ret = rte_eth_dev_get_port_by_name(name, &port_id); 164 RTE_ASSERT(!ret); 165 166 /* 167 * To make bond_ethdev_configure() happy we need to free the 168 * internals->kvlist here. 169 * 170 * Also see comment in bond_ethdev_configure(). 171 */ 172 internals = rte_eth_devices[port_id].data->dev_private; 173 rte_kvargs_free(internals->kvlist); 174 internals->kvlist = NULL; 175 176 return port_id; 177 } 178 179 int 180 rte_eth_bond_free(const char *name) 181 { 182 return rte_vdev_uninit(name); 183 } 184 185 static int 186 slave_vlan_filter_set(uint16_t bonded_port_id, uint16_t slave_port_id) 187 { 188 struct rte_eth_dev *bonded_eth_dev; 189 struct bond_dev_private *internals; 190 int found; 191 int res = 0; 192 uint64_t slab = 0; 193 uint32_t pos = 0; 194 uint16_t first; 195 196 bonded_eth_dev = &rte_eth_devices[bonded_port_id]; 197 if ((bonded_eth_dev->data->dev_conf.rxmode.offloads & 198 DEV_RX_OFFLOAD_VLAN_FILTER) == 0) 199 return 0; 200 201 internals = bonded_eth_dev->data->dev_private; 202 found = rte_bitmap_scan(internals->vlan_filter_bmp, &pos, &slab); 203 first = pos; 204 205 if (!found) 206 return 0; 207 208 do { 209 uint32_t i; 210 uint64_t mask; 211 212 for (i = 0, mask = 1; 213 i < RTE_BITMAP_SLAB_BIT_SIZE; 214 i ++, mask <<= 1) { 215 if (unlikely(slab & mask)) { 216 uint16_t vlan_id = pos + i; 217 218 res = rte_eth_dev_vlan_filter(slave_port_id, 219 vlan_id, 1); 220 } 221 } 222 found = rte_bitmap_scan(internals->vlan_filter_bmp, 223 &pos, &slab); 224 } while (found && first != pos && res == 0); 225 226 return res; 227 } 228 229 static int 230 slave_rte_flow_prepare(uint16_t slave_id, struct bond_dev_private *internals) 231 { 232 struct rte_flow *flow; 233 struct rte_flow_error ferror; 234 uint16_t slave_port_id = internals->slaves[slave_id].port_id; 235 236 if (internals->flow_isolated_valid != 0) { 237 rte_eth_dev_stop(slave_port_id); 238 if (rte_flow_isolate(slave_port_id, internals->flow_isolated, 239 &ferror)) { 240 RTE_BOND_LOG(ERR, "rte_flow_isolate failed for slave" 241 " %d: %s", slave_id, ferror.message ? 242 ferror.message : "(no stated reason)"); 243 return -1; 244 } 245 } 246 TAILQ_FOREACH(flow, &internals->flow_list, next) { 247 flow->flows[slave_id] = rte_flow_create(slave_port_id, 248 &flow->fd->attr, 249 flow->fd->items, 250 flow->fd->actions, 251 &ferror); 252 if (flow->flows[slave_id] == NULL) { 253 RTE_BOND_LOG(ERR, "Cannot create flow for slave" 254 " %d: %s", slave_id, 255 ferror.message ? ferror.message : 256 "(no stated reason)"); 257 /* Destroy successful bond flows from the slave */ 258 TAILQ_FOREACH(flow, &internals->flow_list, next) { 259 if (flow->flows[slave_id] != NULL) { 260 rte_flow_destroy(slave_port_id, 261 flow->flows[slave_id], 262 &ferror); 263 flow->flows[slave_id] = NULL; 264 } 265 } 266 return -1; 267 } 268 } 269 return 0; 270 } 271 272 static int 273 __eth_bond_slave_add_lock_free(uint16_t bonded_port_id, uint16_t slave_port_id) 274 { 275 struct rte_eth_dev *bonded_eth_dev, *slave_eth_dev; 276 struct bond_dev_private *internals; 277 struct rte_eth_link link_props; 278 struct rte_eth_dev_info dev_info; 279 280 bonded_eth_dev = &rte_eth_devices[bonded_port_id]; 281 internals = bonded_eth_dev->data->dev_private; 282 283 if (valid_slave_port_id(slave_port_id, internals->mode) != 0) 284 return -1; 285 286 slave_eth_dev = &rte_eth_devices[slave_port_id]; 287 if (slave_eth_dev->data->dev_flags & RTE_ETH_DEV_BONDED_SLAVE) { 288 RTE_BOND_LOG(ERR, "Slave device is already a slave of a bonded device"); 289 return -1; 290 } 291 292 rte_eth_dev_info_get(slave_port_id, &dev_info); 293 if (dev_info.max_rx_pktlen < internals->max_rx_pktlen) { 294 RTE_BOND_LOG(ERR, "Slave (port %u) max_rx_pktlen too small", 295 slave_port_id); 296 return -1; 297 } 298 299 slave_add(internals, slave_eth_dev); 300 301 /* We need to store slaves reta_size to be able to synchronize RETA for all 302 * slave devices even if its sizes are different. 303 */ 304 internals->slaves[internals->slave_count].reta_size = dev_info.reta_size; 305 306 if (internals->slave_count < 1) { 307 /* if MAC is not user defined then use MAC of first slave add to 308 * bonded device */ 309 if (!internals->user_defined_mac) { 310 if (mac_address_set(bonded_eth_dev, 311 slave_eth_dev->data->mac_addrs)) { 312 RTE_BOND_LOG(ERR, "Failed to set MAC address"); 313 return -1; 314 } 315 } 316 317 /* Inherit eth dev link properties from first slave */ 318 link_properties_set(bonded_eth_dev, 319 &(slave_eth_dev->data->dev_link)); 320 321 /* Make primary slave */ 322 internals->primary_port = slave_port_id; 323 internals->current_primary_port = slave_port_id; 324 325 /* Inherit queues settings from first slave */ 326 internals->nb_rx_queues = slave_eth_dev->data->nb_rx_queues; 327 internals->nb_tx_queues = slave_eth_dev->data->nb_tx_queues; 328 329 internals->reta_size = dev_info.reta_size; 330 331 /* Take the first dev's offload capabilities */ 332 internals->rx_offload_capa = dev_info.rx_offload_capa; 333 internals->tx_offload_capa = dev_info.tx_offload_capa; 334 internals->rx_queue_offload_capa = dev_info.rx_queue_offload_capa; 335 internals->tx_queue_offload_capa = dev_info.tx_queue_offload_capa; 336 internals->flow_type_rss_offloads = dev_info.flow_type_rss_offloads; 337 338 /* Inherit first slave's max rx packet size */ 339 internals->candidate_max_rx_pktlen = dev_info.max_rx_pktlen; 340 341 } else { 342 internals->rx_offload_capa &= dev_info.rx_offload_capa; 343 internals->tx_offload_capa &= dev_info.tx_offload_capa; 344 internals->rx_queue_offload_capa &= dev_info.rx_queue_offload_capa; 345 internals->tx_queue_offload_capa &= dev_info.tx_queue_offload_capa; 346 internals->flow_type_rss_offloads &= dev_info.flow_type_rss_offloads; 347 348 if (link_properties_valid(bonded_eth_dev, 349 &slave_eth_dev->data->dev_link) != 0) { 350 RTE_BOND_LOG(ERR, "Invalid link properties for slave %d" 351 " in bonding mode %d", slave_port_id, 352 internals->mode); 353 return -1; 354 } 355 356 /* RETA size is GCD of all slaves RETA sizes, so, if all sizes will be 357 * the power of 2, the lower one is GCD 358 */ 359 if (internals->reta_size > dev_info.reta_size) 360 internals->reta_size = dev_info.reta_size; 361 362 if (!internals->max_rx_pktlen && 363 dev_info.max_rx_pktlen < internals->candidate_max_rx_pktlen) 364 internals->candidate_max_rx_pktlen = dev_info.max_rx_pktlen; 365 } 366 367 bonded_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf &= 368 internals->flow_type_rss_offloads; 369 370 if (slave_rte_flow_prepare(internals->slave_count, internals) != 0) { 371 RTE_BOND_LOG(ERR, "Failed to prepare new slave flows: port=%d", 372 slave_port_id); 373 return -1; 374 } 375 376 internals->slave_count++; 377 378 if (bonded_eth_dev->data->dev_started) { 379 if (slave_configure(bonded_eth_dev, slave_eth_dev) != 0) { 380 internals->slave_count--; 381 RTE_BOND_LOG(ERR, "rte_bond_slaves_configure: port=%d", 382 slave_port_id); 383 return -1; 384 } 385 } 386 387 /* Add slave details to bonded device */ 388 slave_eth_dev->data->dev_flags |= RTE_ETH_DEV_BONDED_SLAVE; 389 390 /* Update all slave devices MACs*/ 391 mac_address_slaves_update(bonded_eth_dev); 392 393 /* Register link status change callback with bonded device pointer as 394 * argument*/ 395 rte_eth_dev_callback_register(slave_port_id, RTE_ETH_EVENT_INTR_LSC, 396 bond_ethdev_lsc_event_callback, &bonded_eth_dev->data->port_id); 397 398 /* If bonded device is started then we can add the slave to our active 399 * slave array */ 400 if (bonded_eth_dev->data->dev_started) { 401 rte_eth_link_get_nowait(slave_port_id, &link_props); 402 403 if (link_props.link_status == ETH_LINK_UP) { 404 if (internals->active_slave_count == 0 && 405 !internals->user_defined_primary_port) 406 bond_ethdev_primary_set(internals, 407 slave_port_id); 408 409 if (find_slave_by_id(internals->active_slaves, 410 internals->active_slave_count, 411 slave_port_id) == internals->active_slave_count) 412 activate_slave(bonded_eth_dev, slave_port_id); 413 } 414 } 415 416 slave_vlan_filter_set(bonded_port_id, slave_port_id); 417 418 return 0; 419 420 } 421 422 int 423 rte_eth_bond_slave_add(uint16_t bonded_port_id, uint16_t slave_port_id) 424 { 425 struct rte_eth_dev *bonded_eth_dev; 426 struct bond_dev_private *internals; 427 428 int retval; 429 430 /* Verify that port id's are valid bonded and slave ports */ 431 if (valid_bonded_port_id(bonded_port_id) != 0) 432 return -1; 433 434 bonded_eth_dev = &rte_eth_devices[bonded_port_id]; 435 internals = bonded_eth_dev->data->dev_private; 436 437 rte_spinlock_lock(&internals->lock); 438 439 retval = __eth_bond_slave_add_lock_free(bonded_port_id, slave_port_id); 440 441 rte_spinlock_unlock(&internals->lock); 442 443 return retval; 444 } 445 446 static int 447 __eth_bond_slave_remove_lock_free(uint16_t bonded_port_id, 448 uint16_t slave_port_id) 449 { 450 struct rte_eth_dev *bonded_eth_dev; 451 struct bond_dev_private *internals; 452 struct rte_eth_dev *slave_eth_dev; 453 struct rte_flow_error flow_error; 454 struct rte_flow *flow; 455 int i, slave_idx; 456 457 bonded_eth_dev = &rte_eth_devices[bonded_port_id]; 458 internals = bonded_eth_dev->data->dev_private; 459 460 if (valid_slave_port_id(slave_port_id, internals->mode) < 0) 461 return -1; 462 463 /* first remove from active slave list */ 464 slave_idx = find_slave_by_id(internals->active_slaves, 465 internals->active_slave_count, slave_port_id); 466 467 if (slave_idx < internals->active_slave_count) 468 deactivate_slave(bonded_eth_dev, slave_port_id); 469 470 slave_idx = -1; 471 /* now find in slave list */ 472 for (i = 0; i < internals->slave_count; i++) 473 if (internals->slaves[i].port_id == slave_port_id) { 474 slave_idx = i; 475 break; 476 } 477 478 if (slave_idx < 0) { 479 RTE_BOND_LOG(ERR, "Couldn't find slave in port list, slave count %d", 480 internals->slave_count); 481 return -1; 482 } 483 484 /* Un-register link status change callback with bonded device pointer as 485 * argument*/ 486 rte_eth_dev_callback_unregister(slave_port_id, RTE_ETH_EVENT_INTR_LSC, 487 bond_ethdev_lsc_event_callback, 488 &rte_eth_devices[bonded_port_id].data->port_id); 489 490 /* Restore original MAC address of slave device */ 491 rte_eth_dev_default_mac_addr_set(slave_port_id, 492 &(internals->slaves[slave_idx].persisted_mac_addr)); 493 494 /* 495 * Remove bond device flows from slave device. 496 * Note: don't restore flow isolate mode. 497 */ 498 TAILQ_FOREACH(flow, &internals->flow_list, next) { 499 if (flow->flows[slave_idx] != NULL) { 500 rte_flow_destroy(slave_port_id, flow->flows[slave_idx], 501 &flow_error); 502 flow->flows[slave_idx] = NULL; 503 } 504 } 505 506 slave_eth_dev = &rte_eth_devices[slave_port_id]; 507 slave_remove(internals, slave_eth_dev); 508 slave_eth_dev->data->dev_flags &= (~RTE_ETH_DEV_BONDED_SLAVE); 509 510 /* first slave in the active list will be the primary by default, 511 * otherwise use first device in list */ 512 if (internals->current_primary_port == slave_port_id) { 513 if (internals->active_slave_count > 0) 514 internals->current_primary_port = internals->active_slaves[0]; 515 else if (internals->slave_count > 0) 516 internals->current_primary_port = internals->slaves[0].port_id; 517 else 518 internals->primary_port = 0; 519 } 520 521 if (internals->active_slave_count < 1) { 522 /* if no slaves are any longer attached to bonded device and MAC is not 523 * user defined then clear MAC of bonded device as it will be reset 524 * when a new slave is added */ 525 if (internals->slave_count < 1 && !internals->user_defined_mac) 526 memset(rte_eth_devices[bonded_port_id].data->mac_addrs, 0, 527 sizeof(*(rte_eth_devices[bonded_port_id].data->mac_addrs))); 528 } 529 if (internals->slave_count == 0) { 530 internals->rx_offload_capa = 0; 531 internals->tx_offload_capa = 0; 532 internals->rx_queue_offload_capa = 0; 533 internals->tx_queue_offload_capa = 0; 534 internals->flow_type_rss_offloads = ETH_RSS_PROTO_MASK; 535 internals->reta_size = 0; 536 internals->candidate_max_rx_pktlen = 0; 537 internals->max_rx_pktlen = 0; 538 } 539 return 0; 540 } 541 542 int 543 rte_eth_bond_slave_remove(uint16_t bonded_port_id, uint16_t slave_port_id) 544 { 545 struct rte_eth_dev *bonded_eth_dev; 546 struct bond_dev_private *internals; 547 int retval; 548 549 if (valid_bonded_port_id(bonded_port_id) != 0) 550 return -1; 551 552 bonded_eth_dev = &rte_eth_devices[bonded_port_id]; 553 internals = bonded_eth_dev->data->dev_private; 554 555 rte_spinlock_lock(&internals->lock); 556 557 retval = __eth_bond_slave_remove_lock_free(bonded_port_id, slave_port_id); 558 559 rte_spinlock_unlock(&internals->lock); 560 561 return retval; 562 } 563 564 int 565 rte_eth_bond_mode_set(uint16_t bonded_port_id, uint8_t mode) 566 { 567 struct rte_eth_dev *bonded_eth_dev; 568 569 if (valid_bonded_port_id(bonded_port_id) != 0) 570 return -1; 571 572 bonded_eth_dev = &rte_eth_devices[bonded_port_id]; 573 574 if (check_for_master_bonded_ethdev(bonded_eth_dev) != 0 && 575 mode == BONDING_MODE_8023AD) 576 return -1; 577 578 return bond_ethdev_mode_set(bonded_eth_dev, mode); 579 } 580 581 int 582 rte_eth_bond_mode_get(uint16_t bonded_port_id) 583 { 584 struct bond_dev_private *internals; 585 586 if (valid_bonded_port_id(bonded_port_id) != 0) 587 return -1; 588 589 internals = rte_eth_devices[bonded_port_id].data->dev_private; 590 591 return internals->mode; 592 } 593 594 int 595 rte_eth_bond_primary_set(uint16_t bonded_port_id, uint16_t slave_port_id) 596 { 597 struct bond_dev_private *internals; 598 599 if (valid_bonded_port_id(bonded_port_id) != 0) 600 return -1; 601 602 internals = rte_eth_devices[bonded_port_id].data->dev_private; 603 604 if (valid_slave_port_id(slave_port_id, internals->mode) != 0) 605 return -1; 606 607 internals->user_defined_primary_port = 1; 608 internals->primary_port = slave_port_id; 609 610 bond_ethdev_primary_set(internals, slave_port_id); 611 612 return 0; 613 } 614 615 int 616 rte_eth_bond_primary_get(uint16_t bonded_port_id) 617 { 618 struct bond_dev_private *internals; 619 620 if (valid_bonded_port_id(bonded_port_id) != 0) 621 return -1; 622 623 internals = rte_eth_devices[bonded_port_id].data->dev_private; 624 625 if (internals->slave_count < 1) 626 return -1; 627 628 return internals->current_primary_port; 629 } 630 631 int 632 rte_eth_bond_slaves_get(uint16_t bonded_port_id, uint16_t slaves[], 633 uint16_t len) 634 { 635 struct bond_dev_private *internals; 636 uint8_t i; 637 638 if (valid_bonded_port_id(bonded_port_id) != 0) 639 return -1; 640 641 if (slaves == NULL) 642 return -1; 643 644 internals = rte_eth_devices[bonded_port_id].data->dev_private; 645 646 if (internals->slave_count > len) 647 return -1; 648 649 for (i = 0; i < internals->slave_count; i++) 650 slaves[i] = internals->slaves[i].port_id; 651 652 return internals->slave_count; 653 } 654 655 int 656 rte_eth_bond_active_slaves_get(uint16_t bonded_port_id, uint16_t slaves[], 657 uint16_t len) 658 { 659 struct bond_dev_private *internals; 660 661 if (valid_bonded_port_id(bonded_port_id) != 0) 662 return -1; 663 664 if (slaves == NULL) 665 return -1; 666 667 internals = rte_eth_devices[bonded_port_id].data->dev_private; 668 669 if (internals->active_slave_count > len) 670 return -1; 671 672 memcpy(slaves, internals->active_slaves, 673 internals->active_slave_count * sizeof(internals->active_slaves[0])); 674 675 return internals->active_slave_count; 676 } 677 678 int 679 rte_eth_bond_mac_address_set(uint16_t bonded_port_id, 680 struct ether_addr *mac_addr) 681 { 682 struct rte_eth_dev *bonded_eth_dev; 683 struct bond_dev_private *internals; 684 685 if (valid_bonded_port_id(bonded_port_id) != 0) 686 return -1; 687 688 bonded_eth_dev = &rte_eth_devices[bonded_port_id]; 689 internals = bonded_eth_dev->data->dev_private; 690 691 /* Set MAC Address of Bonded Device */ 692 if (mac_address_set(bonded_eth_dev, mac_addr)) 693 return -1; 694 695 internals->user_defined_mac = 1; 696 697 /* Update all slave devices MACs*/ 698 if (internals->slave_count > 0) 699 return mac_address_slaves_update(bonded_eth_dev); 700 701 return 0; 702 } 703 704 int 705 rte_eth_bond_mac_address_reset(uint16_t bonded_port_id) 706 { 707 struct rte_eth_dev *bonded_eth_dev; 708 struct bond_dev_private *internals; 709 710 if (valid_bonded_port_id(bonded_port_id) != 0) 711 return -1; 712 713 bonded_eth_dev = &rte_eth_devices[bonded_port_id]; 714 internals = bonded_eth_dev->data->dev_private; 715 716 internals->user_defined_mac = 0; 717 718 if (internals->slave_count > 0) { 719 /* Set MAC Address of Bonded Device */ 720 if (mac_address_set(bonded_eth_dev, 721 &internals->slaves[internals->primary_port].persisted_mac_addr) 722 != 0) { 723 RTE_BOND_LOG(ERR, "Failed to set MAC address on bonded device"); 724 return -1; 725 } 726 /* Update all slave devices MAC addresses */ 727 return mac_address_slaves_update(bonded_eth_dev); 728 } 729 /* No need to update anything as no slaves present */ 730 return 0; 731 } 732 733 int 734 rte_eth_bond_xmit_policy_set(uint16_t bonded_port_id, uint8_t policy) 735 { 736 struct bond_dev_private *internals; 737 738 if (valid_bonded_port_id(bonded_port_id) != 0) 739 return -1; 740 741 internals = rte_eth_devices[bonded_port_id].data->dev_private; 742 743 switch (policy) { 744 case BALANCE_XMIT_POLICY_LAYER2: 745 internals->balance_xmit_policy = policy; 746 internals->burst_xmit_hash = burst_xmit_l2_hash; 747 break; 748 case BALANCE_XMIT_POLICY_LAYER23: 749 internals->balance_xmit_policy = policy; 750 internals->burst_xmit_hash = burst_xmit_l23_hash; 751 break; 752 case BALANCE_XMIT_POLICY_LAYER34: 753 internals->balance_xmit_policy = policy; 754 internals->burst_xmit_hash = burst_xmit_l34_hash; 755 break; 756 757 default: 758 return -1; 759 } 760 return 0; 761 } 762 763 int 764 rte_eth_bond_xmit_policy_get(uint16_t bonded_port_id) 765 { 766 struct bond_dev_private *internals; 767 768 if (valid_bonded_port_id(bonded_port_id) != 0) 769 return -1; 770 771 internals = rte_eth_devices[bonded_port_id].data->dev_private; 772 773 return internals->balance_xmit_policy; 774 } 775 776 int 777 rte_eth_bond_link_monitoring_set(uint16_t bonded_port_id, uint32_t internal_ms) 778 { 779 struct bond_dev_private *internals; 780 781 if (valid_bonded_port_id(bonded_port_id) != 0) 782 return -1; 783 784 internals = rte_eth_devices[bonded_port_id].data->dev_private; 785 internals->link_status_polling_interval_ms = internal_ms; 786 787 return 0; 788 } 789 790 int 791 rte_eth_bond_link_monitoring_get(uint16_t bonded_port_id) 792 { 793 struct bond_dev_private *internals; 794 795 if (valid_bonded_port_id(bonded_port_id) != 0) 796 return -1; 797 798 internals = rte_eth_devices[bonded_port_id].data->dev_private; 799 800 return internals->link_status_polling_interval_ms; 801 } 802 803 int 804 rte_eth_bond_link_down_prop_delay_set(uint16_t bonded_port_id, 805 uint32_t delay_ms) 806 807 { 808 struct bond_dev_private *internals; 809 810 if (valid_bonded_port_id(bonded_port_id) != 0) 811 return -1; 812 813 internals = rte_eth_devices[bonded_port_id].data->dev_private; 814 internals->link_down_delay_ms = delay_ms; 815 816 return 0; 817 } 818 819 int 820 rte_eth_bond_link_down_prop_delay_get(uint16_t bonded_port_id) 821 { 822 struct bond_dev_private *internals; 823 824 if (valid_bonded_port_id(bonded_port_id) != 0) 825 return -1; 826 827 internals = rte_eth_devices[bonded_port_id].data->dev_private; 828 829 return internals->link_down_delay_ms; 830 } 831 832 int 833 rte_eth_bond_link_up_prop_delay_set(uint16_t bonded_port_id, uint32_t delay_ms) 834 835 { 836 struct bond_dev_private *internals; 837 838 if (valid_bonded_port_id(bonded_port_id) != 0) 839 return -1; 840 841 internals = rte_eth_devices[bonded_port_id].data->dev_private; 842 internals->link_up_delay_ms = delay_ms; 843 844 return 0; 845 } 846 847 int 848 rte_eth_bond_link_up_prop_delay_get(uint16_t bonded_port_id) 849 { 850 struct bond_dev_private *internals; 851 852 if (valid_bonded_port_id(bonded_port_id) != 0) 853 return -1; 854 855 internals = rte_eth_devices[bonded_port_id].data->dev_private; 856 857 return internals->link_up_delay_ms; 858 } 859