bond: support link status polling
Signed-off-by: Declan Doherty <declan.doherty@intel.com> Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com> Tested-by: SunX Jiajia <sunx.jiajia@intel.com>
This commit is contained in:
parent
620f98d66f
commit
a45b288ef2
@ -462,6 +462,9 @@ static void cmd_help_long_parsed(void *parsed_result,
|
||||
|
||||
"set bonding xmit_balance_policy (port_id) (l2|l23|l34)\n"
|
||||
" Set the transmit balance policy for bonded device running in balance mode.\n\n"
|
||||
|
||||
"set bonding mon_period (port_id) (value)\n"
|
||||
" Set the bonding link status monitoring polling period in ms.\n\n"
|
||||
#endif
|
||||
"set link-up port (port_id)\n"
|
||||
" Set link up for a port.\n\n"
|
||||
@ -3738,6 +3741,65 @@ cmdline_parse_inst_t cmd_set_bond_mac_addr = {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* *** SET LINK STATUS MONITORING POLLING PERIOD ON BONDED DEVICE *** */
|
||||
struct cmd_set_bond_mon_period_result {
|
||||
cmdline_fixed_string_t set;
|
||||
cmdline_fixed_string_t bonding;
|
||||
cmdline_fixed_string_t mon_period;
|
||||
uint8_t port_num;
|
||||
uint32_t period_ms;
|
||||
};
|
||||
|
||||
static void cmd_set_bond_mon_period_parsed(void *parsed_result,
|
||||
__attribute__((unused)) struct cmdline *cl,
|
||||
__attribute__((unused)) void *data)
|
||||
{
|
||||
struct cmd_set_bond_mon_period_result *res = parsed_result;
|
||||
int ret;
|
||||
|
||||
if (res->port_num >= nb_ports) {
|
||||
printf("Port id %d must be less than %d\n", res->port_num, nb_ports);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = rte_eth_bond_link_monitoring_set(res->port_num, res->period_ms);
|
||||
|
||||
/* check the return value and print it if is < 0 */
|
||||
if (ret < 0)
|
||||
printf("set_bond_mac_addr error: (%s)\n", strerror(-ret));
|
||||
}
|
||||
|
||||
cmdline_parse_token_string_t cmd_set_bond_mon_period_set =
|
||||
TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
|
||||
set, "set");
|
||||
cmdline_parse_token_string_t cmd_set_bond_mon_period_bonding =
|
||||
TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
|
||||
bonding, "bonding");
|
||||
cmdline_parse_token_string_t cmd_set_bond_mon_period_mon_period =
|
||||
TOKEN_STRING_INITIALIZER(struct cmd_set_bond_mon_period_result,
|
||||
mon_period, "mon_period");
|
||||
cmdline_parse_token_num_t cmd_set_bond_mon_period_portnum =
|
||||
TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
|
||||
port_num, UINT8);
|
||||
cmdline_parse_token_num_t cmd_set_bond_mon_period_period_ms =
|
||||
TOKEN_NUM_INITIALIZER(struct cmd_set_bond_mon_period_result,
|
||||
period_ms, UINT32);
|
||||
|
||||
cmdline_parse_inst_t cmd_set_bond_mon_period = {
|
||||
.f = cmd_set_bond_mon_period_parsed,
|
||||
.data = (void *) 0,
|
||||
.help_str = "set bonding mon_period (port_id) (period_ms): ",
|
||||
.tokens = {
|
||||
(void *)&cmd_set_bond_mon_period_set,
|
||||
(void *)&cmd_set_bond_mon_period_bonding,
|
||||
(void *)&cmd_set_bond_mon_period_mon_period,
|
||||
(void *)&cmd_set_bond_mon_period_portnum,
|
||||
(void *)&cmd_set_bond_mon_period_period_ms,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* RTE_LIBRTE_PMD_BOND */
|
||||
|
||||
/* *** SET FORWARDING MODE *** */
|
||||
@ -7792,6 +7854,7 @@ cmdline_parse_ctx_t main_ctx[] = {
|
||||
(cmdline_parse_inst_t *) &cmd_create_bonded_device,
|
||||
(cmdline_parse_inst_t *) &cmd_set_bond_mac_addr,
|
||||
(cmdline_parse_inst_t *) &cmd_set_balance_xmit_policy,
|
||||
(cmdline_parse_inst_t *) &cmd_set_bond_mon_period,
|
||||
#endif
|
||||
(cmdline_parse_inst_t *)&cmd_vlan_offload,
|
||||
(cmdline_parse_inst_t *)&cmd_vlan_tpid,
|
||||
|
@ -62,14 +62,15 @@
|
||||
|
||||
#define TEST_ASSERT_SUCCESS(val, msg, ...) do { \
|
||||
if (!(val == 0)) { \
|
||||
printf("TestCase %s() line %d failed: " \
|
||||
msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
|
||||
printf("TestCase %s() line %d failed (err %d): " \
|
||||
msg "\n", __func__, __LINE__, val, \
|
||||
##__VA_ARGS__); \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define TEST_ASSERT_FAIL(val, msg, ...) do { \
|
||||
if (!(val != -1)) { \
|
||||
if (!(val != 0)) { \
|
||||
printf("TestCase %s() line %d failed: " \
|
||||
msg "\n", __func__, __LINE__, ##__VA_ARGS__); \
|
||||
return -1; \
|
||||
|
@ -234,42 +234,34 @@ configure_ethdev(uint8_t port_id, uint8_t start, uint8_t en_isr)
|
||||
else
|
||||
default_pmd_conf.intr_conf.lsc = 0;
|
||||
|
||||
if (rte_eth_dev_configure(port_id, test_params->nb_rx_q,
|
||||
test_params->nb_tx_q, &default_pmd_conf) != 0) {
|
||||
goto error;
|
||||
}
|
||||
TEST_ASSERT_SUCCESS(rte_eth_dev_configure(port_id, test_params->nb_rx_q,
|
||||
test_params->nb_tx_q, &default_pmd_conf),
|
||||
"rte_eth_dev_configure for port %d failed", port_id);
|
||||
|
||||
for (q_id = 0; q_id < test_params->nb_rx_q; q_id++) {
|
||||
if (rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
|
||||
for (q_id = 0; q_id < test_params->nb_rx_q; q_id++)
|
||||
TEST_ASSERT_SUCCESS(rte_eth_rx_queue_setup(port_id, q_id, RX_RING_SIZE,
|
||||
rte_eth_dev_socket_id(port_id), &rx_conf_default,
|
||||
test_params->mbuf_pool) < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
test_params->mbuf_pool) ,
|
||||
"rte_eth_rx_queue_setup for port %d failed", port_id);
|
||||
|
||||
for (q_id = 0; q_id < test_params->nb_tx_q; q_id++) {
|
||||
if (rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
|
||||
rte_eth_dev_socket_id(port_id), &tx_conf_default) < 0) {
|
||||
printf("Failed to setup tx queue (%d).\n", q_id);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
for (q_id = 0; q_id < test_params->nb_tx_q; q_id++)
|
||||
TEST_ASSERT_SUCCESS(rte_eth_tx_queue_setup(port_id, q_id, TX_RING_SIZE,
|
||||
rte_eth_dev_socket_id(port_id), &tx_conf_default),
|
||||
"rte_eth_tx_queue_setup for port %d failed", port_id);
|
||||
|
||||
if (start)
|
||||
TEST_ASSERT_SUCCESS(rte_eth_dev_start(port_id),
|
||||
"rte_eth_dev_start for port %d failed", port_id);
|
||||
|
||||
if (start) {
|
||||
if (rte_eth_dev_start(port_id) < 0) {
|
||||
printf("Failed to start device (%d).\n", port_id);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
error:
|
||||
printf("Failed to configure ethdev %d\n", port_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int slaves_initialized;
|
||||
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t cvar = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
|
||||
static int
|
||||
test_setup(void)
|
||||
{
|
||||
@ -310,7 +302,7 @@ test_setup(void)
|
||||
snprintf(pmd_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_%d", i);
|
||||
|
||||
test_params->slave_port_ids[i] = virtual_ethdev_create(pmd_name,
|
||||
mac_addr, rte_socket_id());
|
||||
mac_addr, rte_socket_id(), 1);
|
||||
if (test_params->slave_port_ids[i] < 0) {
|
||||
printf("Failed to create virtual virtual ethdev %s\n", pmd_name);
|
||||
return -1;
|
||||
@ -414,34 +406,27 @@ test_create_bonded_device_with_invalid_params(void)
|
||||
static int
|
||||
test_add_slave_to_bonded_device(void)
|
||||
{
|
||||
int retval, current_slave_count;
|
||||
int current_slave_count;
|
||||
|
||||
uint8_t slaves[RTE_MAX_ETHPORTS];
|
||||
|
||||
retval = rte_eth_bond_slave_add(test_params->bonded_port_id,
|
||||
test_params->slave_port_ids[test_params->bonded_slave_count]);
|
||||
if (retval != 0) {
|
||||
printf("Failed to add slave (%d) to bonded port (%d).\n",
|
||||
test_params->bonded_port_id,
|
||||
test_params->slave_port_ids[test_params->bonded_slave_count]);
|
||||
return -1;
|
||||
}
|
||||
TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
|
||||
test_params->slave_port_ids[test_params->bonded_slave_count]),
|
||||
"Failed to add slave (%d) to bonded port (%d).",
|
||||
test_params->slave_port_ids[test_params->bonded_slave_count],
|
||||
test_params->bonded_port_id);
|
||||
|
||||
current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
|
||||
slaves, RTE_MAX_ETHPORTS);
|
||||
if (current_slave_count != test_params->bonded_slave_count + 1) {
|
||||
printf("Number of slaves (%d) is greater than expected (%d).\n",
|
||||
current_slave_count, test_params->bonded_slave_count + 1);
|
||||
return -1;
|
||||
}
|
||||
TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count + 1,
|
||||
"Number of slaves (%d) is greater than expected (%d).",
|
||||
current_slave_count, test_params->bonded_slave_count + 1);
|
||||
|
||||
current_slave_count = rte_eth_bond_active_slaves_get(
|
||||
test_params->bonded_port_id, slaves, RTE_MAX_ETHPORTS);
|
||||
if (current_slave_count != 0) {
|
||||
printf("Number of active slaves (%d) is not as expected (%d).\n",
|
||||
current_slave_count, 0);
|
||||
return -1;
|
||||
}
|
||||
TEST_ASSERT_EQUAL(current_slave_count, 0,
|
||||
"Number of active slaves (%d) is not as expected (%d).\n",
|
||||
current_slave_count, 0);
|
||||
|
||||
test_params->bonded_slave_count++;
|
||||
|
||||
@ -476,27 +461,23 @@ test_add_slave_to_invalid_bonded_device(void)
|
||||
static int
|
||||
test_remove_slave_from_bonded_device(void)
|
||||
{
|
||||
int retval, current_slave_count;
|
||||
int current_slave_count;
|
||||
struct ether_addr read_mac_addr, *mac_addr;
|
||||
uint8_t slaves[RTE_MAX_ETHPORTS];
|
||||
|
||||
retval = rte_eth_bond_slave_remove(test_params->bonded_port_id,
|
||||
test_params->slave_port_ids[test_params->bonded_slave_count-1]);
|
||||
if (retval != 0) {
|
||||
printf("\t Failed to remove slave %d from bonded port (%d).\n",
|
||||
test_params->slave_port_ids[test_params->bonded_slave_count-1],
|
||||
test_params->bonded_port_id);
|
||||
return -1;
|
||||
}
|
||||
TEST_ASSERT_SUCCESS(rte_eth_bond_slave_remove(test_params->bonded_port_id,
|
||||
test_params->slave_port_ids[test_params->bonded_slave_count-1]),
|
||||
"Failed to remove slave %d from bonded port (%d).",
|
||||
test_params->slave_port_ids[test_params->bonded_slave_count-1],
|
||||
test_params->bonded_port_id);
|
||||
|
||||
|
||||
current_slave_count = rte_eth_bond_slaves_get(test_params->bonded_port_id,
|
||||
slaves, RTE_MAX_ETHPORTS);
|
||||
if (current_slave_count != test_params->bonded_slave_count - 1) {
|
||||
printf("Number of slaves (%d) is great than expected (%d).\n",
|
||||
current_slave_count, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL(current_slave_count, test_params->bonded_slave_count - 1,
|
||||
"Number of slaves (%d) is great than expected (%d).\n",
|
||||
current_slave_count, test_params->bonded_slave_count - 1);
|
||||
|
||||
|
||||
mac_addr = (struct ether_addr *)slave_mac;
|
||||
@ -506,10 +487,8 @@ test_remove_slave_from_bonded_device(void)
|
||||
rte_eth_macaddr_get(
|
||||
test_params->slave_port_ids[test_params->bonded_slave_count-1],
|
||||
&read_mac_addr);
|
||||
if (memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr))) {
|
||||
printf("bonded port mac address not set to that of primary port\n");
|
||||
return -1;
|
||||
}
|
||||
TEST_ASSERT_SUCCESS(memcmp(mac_addr, &read_mac_addr, sizeof(read_mac_addr)),
|
||||
"bonded port mac address not set to that of primary port\n");
|
||||
|
||||
rte_eth_stats_reset(
|
||||
test_params->slave_port_ids[test_params->bonded_slave_count-1]);
|
||||
@ -891,21 +870,20 @@ test_set_primary_slave(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Non bonded device */
|
||||
retval = rte_eth_bond_primary_set(test_params->slave_port_ids[i],
|
||||
test_params->slave_port_ids[i]);
|
||||
if (retval == 0) {
|
||||
printf("Expected call to failed as invalid port specified.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set slave as primary
|
||||
* Verify slave it is now primary slave
|
||||
* Verify that MAC address of bonded device is that of primary slave
|
||||
* Verify that MAC address of all bonded slaves are that of primary slave
|
||||
*/
|
||||
for (i = 0; i < 4; i++) {
|
||||
|
||||
/* Non bonded device */
|
||||
retval = rte_eth_bond_primary_set(test_params->slave_port_ids[i],
|
||||
test_params->slave_port_ids[i]);
|
||||
if (retval == 0) {
|
||||
printf("Expected call to failed as invalid port specified.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retval = rte_eth_bond_primary_set(test_params->bonded_port_id,
|
||||
test_params->slave_port_ids[i]);
|
||||
if (retval != 0) {
|
||||
@ -929,6 +907,7 @@ test_set_primary_slave(void)
|
||||
|
||||
/* stop/start bonded eth dev to apply new MAC */
|
||||
rte_eth_dev_stop(test_params->bonded_port_id);
|
||||
|
||||
if (rte_eth_dev_start(test_params->bonded_port_id) != 0)
|
||||
return -1;
|
||||
|
||||
@ -1093,19 +1072,18 @@ static int
|
||||
initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
|
||||
uint8_t number_of_slaves, uint8_t enable_slave)
|
||||
{
|
||||
/* configure bonded device */
|
||||
/* Configure bonded device */
|
||||
TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
|
||||
bond_en_isr), "Failed to configure bonding port (%d) in mode %d "
|
||||
"with (%d) slaves.", test_params->bonded_port_id, bonding_mode,
|
||||
number_of_slaves);
|
||||
|
||||
while (number_of_slaves > test_params->bonded_slave_count) {
|
||||
/* Add slaves to bonded device */
|
||||
/* Add slaves to bonded device */
|
||||
while (number_of_slaves > test_params->bonded_slave_count)
|
||||
TEST_ASSERT_SUCCESS(test_add_slave_to_bonded_device(),
|
||||
"Failed to add slave (%d to bonding port (%d).",
|
||||
test_params->bonded_slave_count - 1,
|
||||
test_params->bonded_port_id);
|
||||
}
|
||||
|
||||
/* Set link bonding mode */
|
||||
TEST_ASSERT_SUCCESS(rte_eth_bond_mode_set(test_params->bonded_port_id,
|
||||
@ -1128,9 +1106,9 @@ test_adding_slave_after_bonded_device_started(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 4, 0)
|
||||
!= 0)
|
||||
return -1;
|
||||
TEST_ASSERT_SUCCESS(initialize_bonded_device_with_slaves(
|
||||
BONDING_MODE_ROUND_ROBIN, 0, 4, 0),
|
||||
"Failed to add slaves to bonded device");
|
||||
|
||||
/* Enabled slave devices */
|
||||
for (i = 0; i < test_params->bonded_slave_count + 1; i++) {
|
||||
@ -1138,12 +1116,9 @@ test_adding_slave_after_bonded_device_started(void)
|
||||
test_params->slave_port_ids[i], 1);
|
||||
}
|
||||
|
||||
if (rte_eth_bond_slave_add(test_params->bonded_port_id,
|
||||
test_params->slave_port_ids[test_params->bonded_slave_count]) !=
|
||||
0) {
|
||||
printf("\t Failed to add slave to bonded port.\n");
|
||||
return -1;
|
||||
}
|
||||
TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
|
||||
test_params->slave_port_ids[test_params->bonded_slave_count]),
|
||||
"Failed to add slave to bonded port.\n");
|
||||
|
||||
rte_eth_stats_reset(
|
||||
test_params->slave_port_ids[test_params->bonded_slave_count]);
|
||||
@ -1158,8 +1133,6 @@ test_adding_slave_after_bonded_device_started(void)
|
||||
|
||||
int test_lsc_interrupt_count;
|
||||
|
||||
static pthread_mutex_t mutex;
|
||||
static pthread_cond_t cvar;
|
||||
|
||||
static void
|
||||
test_bonding_lsc_event_callback(uint8_t port_id __rte_unused,
|
||||
@ -1183,7 +1156,7 @@ lsc_timeout(int wait_us)
|
||||
gettimeofday(&tp, NULL);
|
||||
|
||||
/* Convert from timeval to timespec */
|
||||
ts.tv_sec = tp.tv_sec;
|
||||
ts.tv_sec = tp.tv_sec;
|
||||
ts.tv_nsec = tp.tv_usec * 1000;
|
||||
ts.tv_nsec += wait_us * 1000;
|
||||
|
||||
@ -1193,6 +1166,9 @@ lsc_timeout(int wait_us)
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
|
||||
if (retval == 0 && test_lsc_interrupt_count < 1)
|
||||
return -1;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -1202,9 +1178,6 @@ test_status_interrupt(void)
|
||||
int slave_count;
|
||||
uint8_t slaves[RTE_MAX_ETHPORTS];
|
||||
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
pthread_cond_init(&cvar, NULL);
|
||||
|
||||
/* initialized bonding device with T slaves */
|
||||
if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 1,
|
||||
TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1) != 0)
|
||||
@ -1284,9 +1257,6 @@ test_status_interrupt(void)
|
||||
RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
|
||||
&test_params->bonded_port_id);
|
||||
|
||||
pthread_mutex_destroy(&mutex);
|
||||
pthread_cond_destroy(&cvar);
|
||||
|
||||
/* Clean up and remove slaves from bonded device */
|
||||
return remove_slaves_and_stop_bonded_device();
|
||||
}
|
||||
@ -1419,6 +1389,7 @@ test_roundrobin_tx_burst(void)
|
||||
return remove_slaves_and_stop_bonded_device();
|
||||
}
|
||||
|
||||
#ifdef RTE_MBUF_REFCNT
|
||||
static int
|
||||
verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
|
||||
{
|
||||
@ -1432,6 +1403,7 @@ verify_mbufs_ref_count(struct rte_mbuf **mbufs, int nb_mbufs, int val)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
@ -1537,11 +1509,12 @@ test_roundrobin_tx_burst_slave_tx_fail(void)
|
||||
(unsigned int)port_stats.opackets, slave_expected_tx_count);
|
||||
}
|
||||
|
||||
#ifdef RTE_MBUF_REFCNT
|
||||
/* Verify that all mbufs have a ref value of zero */
|
||||
TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkt_burst[tx_count],
|
||||
TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
|
||||
"mbufs refcnts not as expected");
|
||||
|
||||
#endif
|
||||
free_mbufs(&pkt_burst[tx_count], TEST_RR_SLAVE_TX_FAIL_PACKETS_COUNT);
|
||||
|
||||
/* Clean up and remove slaves from bonded device */
|
||||
@ -2028,6 +2001,101 @@ test_roundrobin_verify_slave_link_status_change_behaviour(void)
|
||||
return remove_slaves_and_stop_bonded_device();
|
||||
}
|
||||
|
||||
#define TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT (2)
|
||||
|
||||
uint8_t polling_slave_mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00 };
|
||||
|
||||
#include "unistd.h"
|
||||
|
||||
int polling_test_slaves[TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT] = { -1, -1 };
|
||||
|
||||
static int
|
||||
test_roundrobin_verfiy_polling_slave_link_status_change(void)
|
||||
{
|
||||
struct ether_addr *mac_addr = (struct ether_addr *)polling_slave_mac;
|
||||
char slave_name[RTE_ETH_NAME_MAX_LEN];
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
|
||||
/* Generate slave name / MAC address */
|
||||
snprintf(slave_name, RTE_ETH_NAME_MAX_LEN, "eth_virt_poll_%d", i);
|
||||
mac_addr->addr_bytes[ETHER_ADDR_LEN-1] = i;
|
||||
|
||||
/* Create slave devices with no ISR Support */
|
||||
if (polling_test_slaves[i] == -1) {
|
||||
polling_test_slaves[i] = virtual_ethdev_create(slave_name, mac_addr,
|
||||
rte_socket_id(), 0);
|
||||
TEST_ASSERT(polling_test_slaves[i] >= 0,
|
||||
"Failed to create virtual virtual ethdev %s\n", slave_name);
|
||||
|
||||
/* Configure slave */
|
||||
TEST_ASSERT_SUCCESS(configure_ethdev(polling_test_slaves[i], 0, 0),
|
||||
"Failed to configure virtual ethdev %s(%d)", slave_name,
|
||||
polling_test_slaves[i]);
|
||||
}
|
||||
|
||||
/* Add slave to bonded device */
|
||||
TEST_ASSERT_SUCCESS(rte_eth_bond_slave_add(test_params->bonded_port_id,
|
||||
polling_test_slaves[i]),
|
||||
"Failed to add slave %s(%d) to bonded device %d",
|
||||
slave_name, polling_test_slaves[i], test_params->bonded_port_id);
|
||||
}
|
||||
|
||||
/* Initialize bonded device */
|
||||
TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 1, 1),
|
||||
"Failed to configure bonded device %d",
|
||||
test_params->bonded_port_id);
|
||||
|
||||
|
||||
/* Register link status change interrupt callback */
|
||||
rte_eth_dev_callback_register(test_params->bonded_port_id,
|
||||
RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
|
||||
&test_params->bonded_port_id);
|
||||
|
||||
/* link status change callback for first slave link up */
|
||||
test_lsc_interrupt_count = 0;
|
||||
|
||||
virtual_ethdev_set_link_status(polling_test_slaves[0], 1);
|
||||
|
||||
TEST_ASSERT_SUCCESS(lsc_timeout(15000), "timed out waiting for interrupt");
|
||||
|
||||
|
||||
/* no link status change callback for second slave link up */
|
||||
test_lsc_interrupt_count = 0;
|
||||
|
||||
virtual_ethdev_set_link_status(polling_test_slaves[1], 1);
|
||||
|
||||
TEST_ASSERT_FAIL(lsc_timeout(15000), "unexpectedly succeeded");
|
||||
|
||||
/* link status change callback for both slave links down */
|
||||
test_lsc_interrupt_count = 0;
|
||||
|
||||
virtual_ethdev_set_link_status(polling_test_slaves[0], 0);
|
||||
virtual_ethdev_set_link_status(polling_test_slaves[1], 0);
|
||||
|
||||
TEST_ASSERT_SUCCESS(lsc_timeout(20000), "timed out waiting for interrupt");
|
||||
|
||||
/* Un-Register link status change interrupt callback */
|
||||
rte_eth_dev_callback_unregister(test_params->bonded_port_id,
|
||||
RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
|
||||
&test_params->bonded_port_id);
|
||||
|
||||
|
||||
/* Clean up and remove slaves from bonded device */
|
||||
for (i = 0; i < TEST_RR_POLLING_LINK_STATUS_SLAVE_COUNT; i++) {
|
||||
|
||||
TEST_ASSERT_SUCCESS(
|
||||
rte_eth_bond_slave_remove(test_params->bonded_port_id,
|
||||
polling_test_slaves[i]),
|
||||
"Failed to remove slave %d from bonded port (%d)",
|
||||
polling_test_slaves[i], test_params->bonded_port_id);
|
||||
}
|
||||
|
||||
return remove_slaves_and_stop_bonded_device();
|
||||
}
|
||||
|
||||
|
||||
/** Active Backup Mode Tests */
|
||||
|
||||
static int
|
||||
@ -3160,10 +3228,12 @@ test_balance_tx_burst_slave_tx_fail(void)
|
||||
(unsigned int)port_stats.opackets,
|
||||
TEST_BAL_SLAVE_TX_FAIL_BURST_SIZE_2);
|
||||
|
||||
#ifdef RTE_MBUF_REFCNT
|
||||
/* Verify that all mbufs have a ref value of zero */
|
||||
TEST_ASSERT_SUCCESS(verify_mbufs_ref_count(&pkts_burst_1[tx_count_1],
|
||||
TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT, 1),
|
||||
"mbufs refcnts not as expected");
|
||||
#endif
|
||||
|
||||
free_mbufs(&pkts_burst_1[tx_count_1],
|
||||
TEST_BAL_SLAVE_TX_FAIL_PACKETS_COUNT);
|
||||
@ -4315,6 +4385,7 @@ static struct unit_test_suite link_bonding_test_suite = {
|
||||
TEST_CASE(test_roundrobin_verify_promiscuous_enable_disable),
|
||||
TEST_CASE(test_roundrobin_verify_mac_assignment),
|
||||
TEST_CASE(test_roundrobin_verify_slave_link_status_change_behaviour),
|
||||
TEST_CASE(test_roundrobin_verfiy_polling_slave_link_status_change),
|
||||
TEST_CASE(test_activebackup_tx_burst),
|
||||
TEST_CASE(test_activebackup_rx_burst),
|
||||
TEST_CASE(test_activebackup_verify_promiscuous_enable_disable),
|
||||
|
@ -455,6 +455,14 @@ virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(uint8_t port_id,
|
||||
dev_private->tx_burst_fail_count = packet_fail_count;
|
||||
}
|
||||
|
||||
void
|
||||
virtual_ethdev_set_link_status(uint8_t port_id, uint8_t link_status)
|
||||
{
|
||||
struct rte_eth_dev *vrtl_eth_dev = &rte_eth_devices[port_id];
|
||||
|
||||
vrtl_eth_dev->data->dev_link.link_status = link_status;
|
||||
}
|
||||
|
||||
void
|
||||
virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id,
|
||||
uint8_t link_status)
|
||||
@ -503,7 +511,7 @@ get_number_of_sockets(void)
|
||||
|
||||
int
|
||||
virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
|
||||
uint8_t socket_id)
|
||||
uint8_t socket_id, uint8_t isr_support)
|
||||
{
|
||||
struct rte_pci_device *pci_dev = NULL;
|
||||
struct rte_eth_dev *eth_dev = NULL;
|
||||
@ -553,7 +561,12 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
|
||||
pci_dev->numa_node = socket_id;
|
||||
pci_drv->name = virtual_ethdev_driver_name;
|
||||
pci_drv->id_table = id_table;
|
||||
pci_drv->drv_flags = RTE_PCI_DRV_INTR_LSC;
|
||||
|
||||
if (isr_support)
|
||||
pci_drv->drv_flags |= RTE_PCI_DRV_INTR_LSC;
|
||||
else
|
||||
pci_drv->drv_flags &= ~RTE_PCI_DRV_INTR_LSC;
|
||||
|
||||
|
||||
eth_drv->pci_drv = (struct rte_pci_driver)(*pci_drv);
|
||||
eth_dev->driver = eth_drv;
|
||||
|
@ -40,38 +40,58 @@ extern "C" {
|
||||
|
||||
#include <rte_ether.h>
|
||||
|
||||
int virtual_ethdev_init(void);
|
||||
int
|
||||
virtual_ethdev_init(void);
|
||||
|
||||
int virtual_ethdev_create(const char *name, struct ether_addr *mac_addr, uint8_t socket_id);
|
||||
int
|
||||
virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
|
||||
uint8_t socket_id, uint8_t isr_support);
|
||||
|
||||
void virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id, uint8_t link_status);
|
||||
void
|
||||
virtual_ethdev_set_link_status(uint8_t port_id, uint8_t link_status);
|
||||
|
||||
void virtual_ethdev_add_mbufs_to_rx_queue(uint8_t port_id, struct rte_mbuf **pkts_burst, int burst_length);
|
||||
void
|
||||
virtual_ethdev_simulate_link_status_interrupt(uint8_t port_id,
|
||||
uint8_t link_status);
|
||||
|
||||
void
|
||||
virtual_ethdev_add_mbufs_to_rx_queue(uint8_t port_id,
|
||||
struct rte_mbuf **pkts_burst, int burst_length);
|
||||
|
||||
|
||||
/** Control methods for the dev_ops functions pointer to control the behavior of the Virtual PMD */
|
||||
/** Control methods for the dev_ops functions pointer to control the behavior
|
||||
* of the Virtual PMD */
|
||||
|
||||
void virtual_ethdev_start_fn_set_success(uint8_t port_id, uint8_t success);
|
||||
void
|
||||
virtual_ethdev_start_fn_set_success(uint8_t port_id, uint8_t success);
|
||||
|
||||
void virtual_ethdev_stop_fn_set_success(uint8_t port_id, uint8_t success);
|
||||
void
|
||||
virtual_ethdev_stop_fn_set_success(uint8_t port_id, uint8_t success);
|
||||
|
||||
void virtual_ethdev_configure_fn_set_success(uint8_t port_id, uint8_t success);
|
||||
void
|
||||
virtual_ethdev_configure_fn_set_success(uint8_t port_id, uint8_t success);
|
||||
|
||||
void virtual_ethdev_rx_queue_setup_fn_set_success(uint8_t port_id, uint8_t success);
|
||||
void
|
||||
virtual_ethdev_rx_queue_setup_fn_set_success(uint8_t port_id, uint8_t success);
|
||||
|
||||
void virtual_ethdev_tx_queue_setup_fn_set_success(uint8_t port_id, uint8_t success);
|
||||
void
|
||||
virtual_ethdev_tx_queue_setup_fn_set_success(uint8_t port_id, uint8_t success);
|
||||
|
||||
void virtual_ethdev_link_update_fn_set_success(uint8_t port_id, uint8_t success);
|
||||
void
|
||||
virtual_ethdev_link_update_fn_set_success(uint8_t port_id, uint8_t success);
|
||||
|
||||
void virtual_ethdev_rx_burst_fn_set_success(uint8_t port_id, uint8_t success);
|
||||
void
|
||||
virtual_ethdev_rx_burst_fn_set_success(uint8_t port_id, uint8_t success);
|
||||
|
||||
void virtual_ethdev_tx_burst_fn_set_success(uint8_t port_id, uint8_t success);
|
||||
void
|
||||
virtual_ethdev_tx_burst_fn_set_success(uint8_t port_id, uint8_t success);
|
||||
|
||||
/* if a value greater than zero is set for packet_fail_count then virtual
|
||||
* device tx burst function will fail that many packet from burst or all
|
||||
* packets if packet_fail_count is greater than the number of packets in the
|
||||
* burst */
|
||||
void virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(uint8_t port_id,
|
||||
void
|
||||
virtual_ethdev_tx_burst_fn_set_tx_pkt_fail_count(uint8_t port_id,
|
||||
uint8_t packet_fail_count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1479,6 +1479,25 @@ For example, set a Link Bonding device (port 10) to use a balance policy of laye
|
||||
|
||||
testpmd> set bonding xmit_balance_policy 10 l34
|
||||
|
||||
|
||||
set bonding mon_period
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Set the link status monitoring polling period in milliseconds for a bonding devicie.
|
||||
|
||||
This adds support for PMD slave devices which do not support link status interrupts.
|
||||
When the mon_period is set to a value greater than 0 then all PMD's which do not support
|
||||
link status ISR will be queried every polling interval to check if their link status has changed.
|
||||
|
||||
set bonding mon_period (port_id) (value)
|
||||
|
||||
For example, to set the link status monitoring polling period of bonded device (port 5) to 150ms
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
testpmd> set bonding mon_period 5 150
|
||||
|
||||
|
||||
show bonding config
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -249,6 +249,86 @@ rte_eth_bond_xmit_policy_set(uint8_t bonded_port_id, uint8_t policy);
|
||||
int
|
||||
rte_eth_bond_xmit_policy_get(uint8_t bonded_port_id);
|
||||
|
||||
/**
|
||||
* Set the link monitoring frequency (in ms) for monitoring the link status of
|
||||
* slave devices
|
||||
*
|
||||
* @param bonded_port_id Port ID of bonded device.
|
||||
* @param internal_ms Monitoring interval in milliseconds
|
||||
*
|
||||
* @return
|
||||
* 0 on success, negative value otherwise.
|
||||
*/
|
||||
|
||||
int
|
||||
rte_eth_bond_link_monitoring_set(uint8_t bonded_port_id, uint32_t internal_ms);
|
||||
|
||||
/**
|
||||
* Get the current link monitoring frequency (in ms) for monitoring of the link
|
||||
* status of slave devices
|
||||
*
|
||||
* @param bonded_port_id Port ID of bonded device.
|
||||
*
|
||||
* @return
|
||||
* Monitoring interval on success, negative value otherwise.
|
||||
*/
|
||||
int
|
||||
rte_eth_bond_link_monitoring_get(uint8_t bonded_port_id);
|
||||
|
||||
|
||||
/**
|
||||
* Set the period in milliseconds for delaying the disabling of a bonded link
|
||||
* when the link down status has been detected
|
||||
*
|
||||
* @param bonded_port_id Port ID of bonded device.
|
||||
* @param delay_ms Delay period in milliseconds.
|
||||
*
|
||||
* @return
|
||||
* 0 on success, negative value otherwise.
|
||||
*/
|
||||
int
|
||||
rte_eth_bond_link_down_prop_delay_set(uint8_t bonded_port_id, uint32_t delay_ms);
|
||||
|
||||
/**
|
||||
* Get the period in milliseconds set for delaying the disabling of a bonded
|
||||
* link when the link down status has been detected
|
||||
*
|
||||
* @param bonded_port_id Port ID of bonded device.
|
||||
* @param delay_ms Delay period in milliseconds.
|
||||
*
|
||||
* @return
|
||||
* Delay period on success, negative value otherwise.
|
||||
*/
|
||||
int
|
||||
rte_eth_bond_link_down_prop_delay_get(uint8_t bonded_port_id);
|
||||
|
||||
/**
|
||||
* Set the period in milliseconds for delaying the enabling of a bonded link
|
||||
* when the link up status has been detected
|
||||
*
|
||||
* @param bonded_port_id Port ID of bonded device.
|
||||
* @param delay_ms Delay period in milliseconds.
|
||||
*
|
||||
* @return
|
||||
* 0 on success, negative value otherwise.
|
||||
*/
|
||||
int
|
||||
rte_eth_bond_link_up_prop_delay_set(uint8_t bonded_port_id, uint32_t delay_ms);
|
||||
|
||||
/**
|
||||
* Get the period in milliseconds set for delaying the enabling of a bonded
|
||||
* link when the link up status has been detected
|
||||
*
|
||||
* @param bonded_port_id Port ID of bonded device.
|
||||
* @param delay_ms Delay period in milliseconds.
|
||||
*
|
||||
* @return
|
||||
* Delay period on success, negative value otherwise.
|
||||
*/
|
||||
int
|
||||
rte_eth_bond_link_up_prop_delay_get(uint8_t bonded_port_id);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -39,6 +39,8 @@
|
||||
#include "rte_eth_bond.h"
|
||||
#include "rte_eth_bond_private.h"
|
||||
|
||||
#define DEFAULT_POLLING_INTERVAL_10_MS (10)
|
||||
|
||||
int
|
||||
valid_bonded_ethdev(struct rte_eth_dev *eth_dev)
|
||||
{
|
||||
@ -63,9 +65,8 @@ valid_port_id(uint8_t port_id)
|
||||
/* Verify that port id is valid */
|
||||
int ethdev_count = rte_eth_dev_count();
|
||||
if (port_id >= ethdev_count) {
|
||||
RTE_LOG(ERR, PMD,
|
||||
"%s: port Id %d is greater than rte_eth_dev_count %d\n",
|
||||
__func__, port_id, ethdev_count);
|
||||
RTE_BOND_LOG(ERR, "Port Id %d is greater than rte_eth_dev_count %d",
|
||||
port_id, ethdev_count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -81,9 +82,8 @@ valid_bonded_port_id(uint8_t port_id)
|
||||
|
||||
/* Verify that bonded_port_id refers to a bonded port */
|
||||
if (valid_bonded_ethdev(&rte_eth_devices[port_id])) {
|
||||
RTE_LOG(ERR, PMD,
|
||||
"%s: Specified port Id %d is not a bonded eth_dev device\n",
|
||||
__func__, port_id);
|
||||
RTE_BOND_LOG(ERR, "Specified port Id %d is not a bonded eth_dev device",
|
||||
port_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -136,37 +136,36 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id)
|
||||
*/
|
||||
|
||||
if (name == NULL) {
|
||||
RTE_LOG(ERR, PMD, "Invalid name specified\n");
|
||||
RTE_BOND_LOG(ERR, "Invalid name specified");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (socket_id >= number_of_sockets()) {
|
||||
RTE_LOG(ERR, PMD,
|
||||
"%s: invalid socket id specified to create bonded device on.\n",
|
||||
__func__);
|
||||
RTE_BOND_LOG(ERR,
|
||||
"Invalid socket id specified to create bonded device on.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
pci_dev = rte_zmalloc_socket(name, sizeof(*pci_dev), 0, socket_id);
|
||||
if (pci_dev == NULL) {
|
||||
RTE_LOG(ERR, PMD, "Unable to malloc pci dev on socket\n");
|
||||
RTE_BOND_LOG(ERR, "Unable to malloc pci dev on socket");
|
||||
goto err;
|
||||
}
|
||||
|
||||
eth_drv = rte_zmalloc_socket(name, sizeof(*eth_drv), 0, socket_id);
|
||||
if (eth_drv == NULL) {
|
||||
RTE_LOG(ERR, PMD, "Unable to malloc eth_drv on socket\n");
|
||||
RTE_BOND_LOG(ERR, "Unable to malloc eth_drv on socket");
|
||||
goto err;
|
||||
}
|
||||
|
||||
pci_drv = rte_zmalloc_socket(name, sizeof(*pci_drv), 0, socket_id);
|
||||
if (pci_drv == NULL) {
|
||||
RTE_LOG(ERR, PMD, "Unable to malloc pci_drv on socket\n");
|
||||
RTE_BOND_LOG(ERR, "Unable to malloc pci_drv on socket");
|
||||
goto err;
|
||||
}
|
||||
pci_id_table = rte_zmalloc_socket(name, sizeof(*pci_id_table), 0, socket_id);
|
||||
if (pci_drv == NULL) {
|
||||
RTE_LOG(ERR, PMD, "Unable to malloc pci_id_table on socket\n");
|
||||
RTE_BOND_LOG(ERR, "Unable to malloc pci_id_table on socket");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -181,14 +180,14 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id)
|
||||
|
||||
internals = rte_zmalloc_socket(name, sizeof(*internals), 0, socket_id);
|
||||
if (internals == NULL) {
|
||||
RTE_LOG(ERR, PMD, "Unable to malloc internals on socket\n");
|
||||
RTE_BOND_LOG(ERR, "Unable to malloc internals on socket");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* reserve an ethdev entry */
|
||||
eth_dev = rte_eth_dev_allocate(name);
|
||||
if (eth_dev == NULL) {
|
||||
RTE_LOG(ERR, PMD, "Unable to allocate rte_eth_dev\n");
|
||||
RTE_BOND_LOG(ERR, "Unable to allocate rte_eth_dev");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -218,25 +217,31 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id)
|
||||
eth_dev->pci_dev = pci_dev;
|
||||
|
||||
if (bond_ethdev_mode_set(eth_dev, mode)) {
|
||||
RTE_LOG(ERR, PMD,
|
||||
"%s: failed to set bonded device %d mode too %d\n",
|
||||
__func__, eth_dev->data->port_id, mode);
|
||||
RTE_BOND_LOG(ERR, "Failed to set bonded device %d mode too %d",
|
||||
eth_dev->data->port_id, mode);
|
||||
goto err;
|
||||
}
|
||||
|
||||
rte_spinlock_init(&internals->lock);
|
||||
|
||||
internals->port_id = eth_dev->data->port_id;
|
||||
internals->current_primary_port = 0;
|
||||
internals->balance_xmit_policy = BALANCE_XMIT_POLICY_LAYER2;
|
||||
internals->user_defined_mac = 0;
|
||||
internals->link_props_set = 0;
|
||||
|
||||
internals->link_status_polling_enabled = 0;
|
||||
|
||||
internals->link_status_polling_interval_ms = DEFAULT_POLLING_INTERVAL_10_MS;
|
||||
internals->link_down_delay_ms = 0;
|
||||
internals->link_up_delay_ms = 0;
|
||||
|
||||
internals->slave_count = 0;
|
||||
internals->active_slave_count = 0;
|
||||
|
||||
memset(internals->active_slaves, 0, sizeof(internals->active_slaves));
|
||||
memset(internals->slaves, 0, sizeof(internals->slaves));
|
||||
|
||||
memset(internals->presisted_slaves_conf, 0,
|
||||
sizeof(internals->presisted_slaves_conf));
|
||||
|
||||
return eth_dev->data->port_id;
|
||||
|
||||
err:
|
||||
@ -253,8 +258,8 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
rte_eth_bond_slave_add(uint8_t bonded_port_id, uint8_t slave_port_id)
|
||||
static int
|
||||
__eth_bond_slave_add_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id)
|
||||
{
|
||||
struct rte_eth_dev *bonded_eth_dev, *slave_eth_dev;
|
||||
struct bond_dev_private *internals;
|
||||
@ -263,56 +268,43 @@ rte_eth_bond_slave_add(uint8_t bonded_port_id, uint8_t slave_port_id)
|
||||
|
||||
int i, j;
|
||||
|
||||
/* Verify that port id's are valid bonded and slave ports */
|
||||
if (valid_bonded_port_id(bonded_port_id) != 0)
|
||||
goto err_add;
|
||||
|
||||
if (valid_slave_port_id(slave_port_id) != 0)
|
||||
goto err_add;
|
||||
|
||||
/*
|
||||
* Verify that new slave device is not already a slave of another bonded
|
||||
* device */
|
||||
for (i = rte_eth_dev_count()-1; i >= 0; i--) {
|
||||
if (valid_bonded_ethdev(&rte_eth_devices[i]) == 0) {
|
||||
temp_internals = rte_eth_devices[i].data->dev_private;
|
||||
for (j = 0; j < temp_internals->slave_count; j++) {
|
||||
/* Device already a slave of a bonded device */
|
||||
if (temp_internals->slaves[j] == slave_port_id)
|
||||
goto err_add;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
||||
bonded_eth_dev = &rte_eth_devices[bonded_port_id];
|
||||
internals = bonded_eth_dev->data->dev_private;
|
||||
|
||||
slave_eth_dev = &rte_eth_devices[slave_port_id];
|
||||
/* Verify that new slave device is not already a slave of another
|
||||
* bonded device */
|
||||
for (i = rte_eth_dev_count()-1; i >= 0; i--) {
|
||||
if (valid_bonded_ethdev(&rte_eth_devices[i]) == 0) {
|
||||
temp_internals = rte_eth_devices[i].data->dev_private;
|
||||
|
||||
if (internals->slave_count > 0) {
|
||||
/* Check that new slave device is the same type as the other slaves
|
||||
* and not repetitive */
|
||||
for (i = 0; i < internals->slave_count; i++) {
|
||||
if (slave_eth_dev->pci_dev->driver->id_table->device_id !=
|
||||
rte_eth_devices[internals->slaves[i]].pci_dev->driver->id_table->device_id ||
|
||||
internals->slaves[i] == slave_port_id)
|
||||
goto err_add;
|
||||
for (j = 0; j < temp_internals->slave_count; j++) {
|
||||
/* Device already a slave of a bonded device */
|
||||
if (temp_internals->slaves[j].port_id == slave_port_id) {
|
||||
RTE_BOND_LOG(ERR, "Slave port %d is already a slave",
|
||||
slave_port_id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add slave details to bonded device */
|
||||
internals->slaves[internals->slave_count] = slave_port_id;
|
||||
slave_eth_dev = &rte_eth_devices[slave_port_id];
|
||||
|
||||
slave_config_store(internals, slave_eth_dev);
|
||||
/* Add slave details to bonded device */
|
||||
slave_add(internals, slave_eth_dev);
|
||||
|
||||
if (internals->slave_count < 1) {
|
||||
/* if MAC is not user defined then use MAC of first slave add to bonded
|
||||
* device */
|
||||
/* if MAC is not user defined then use MAC of first slave add to
|
||||
* bonded device */
|
||||
if (!internals->user_defined_mac)
|
||||
mac_address_set(bonded_eth_dev, slave_eth_dev->data->mac_addrs);
|
||||
|
||||
/* Inherit eth dev link properties from first slave */
|
||||
link_properties_set(bonded_eth_dev, &(slave_eth_dev->data->dev_link));
|
||||
link_properties_set(bonded_eth_dev,
|
||||
&(slave_eth_dev->data->dev_link));
|
||||
|
||||
/* Make primary slave */
|
||||
internals->primary_port = slave_port_id;
|
||||
@ -322,10 +314,10 @@ rte_eth_bond_slave_add(uint8_t bonded_port_id, uint8_t slave_port_id)
|
||||
if (internals->link_props_set) {
|
||||
if (link_properties_valid(&(bonded_eth_dev->data->dev_link),
|
||||
&(slave_eth_dev->data->dev_link))) {
|
||||
RTE_LOG(ERR, PMD,
|
||||
"%s: Slave port %d link speed/duplex not supported\n",
|
||||
__func__, slave_port_id);
|
||||
goto err_add;
|
||||
RTE_BOND_LOG(ERR,
|
||||
"Slave port %d link speed/duplex not supported",
|
||||
slave_port_id);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
link_properties_set(bonded_eth_dev,
|
||||
@ -340,9 +332,9 @@ rte_eth_bond_slave_add(uint8_t bonded_port_id, uint8_t slave_port_id)
|
||||
|
||||
if (bonded_eth_dev->data->dev_started) {
|
||||
if (slave_configure(bonded_eth_dev, slave_eth_dev) != 0) {
|
||||
RTE_LOG(ERR, PMD, "rte_bond_slaves_configure: port=%d\n",
|
||||
RTE_BOND_LOG(ERR, "rte_bond_slaves_configure: port=%d",
|
||||
slave_port_id);
|
||||
goto err_add;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,65 +348,79 @@ rte_eth_bond_slave_add(uint8_t bonded_port_id, uint8_t slave_port_id)
|
||||
if (bonded_eth_dev->data->dev_started) {
|
||||
rte_eth_link_get_nowait(slave_port_id, &link_props);
|
||||
|
||||
if (link_props.link_status == 1) {
|
||||
if (link_props.link_status == 1)
|
||||
internals->active_slaves[internals->active_slave_count++] =
|
||||
slave_port_id;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_add:
|
||||
RTE_LOG(ERR, PMD, "Failed to add port %d as slave\n", slave_port_id);
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
rte_eth_bond_slave_remove(uint8_t bonded_port_id, uint8_t slave_port_id)
|
||||
{
|
||||
struct bond_dev_private *internals;
|
||||
struct slave_conf *slave_conf;
|
||||
|
||||
int i;
|
||||
int pos = -1;
|
||||
int
|
||||
rte_eth_bond_slave_add(uint8_t bonded_port_id, uint8_t slave_port_id)
|
||||
{
|
||||
struct rte_eth_dev *bonded_eth_dev;
|
||||
struct bond_dev_private *internals;
|
||||
|
||||
int retval;
|
||||
|
||||
/* Verify that port id's are valid bonded and slave ports */
|
||||
if (valid_bonded_port_id(bonded_port_id) != 0)
|
||||
goto err_del;
|
||||
return -1;
|
||||
|
||||
bonded_eth_dev = &rte_eth_devices[bonded_port_id];
|
||||
internals = bonded_eth_dev->data->dev_private;
|
||||
|
||||
rte_spinlock_lock(&internals->lock);
|
||||
|
||||
retval = __eth_bond_slave_add_lock_free(bonded_port_id, slave_port_id);
|
||||
|
||||
rte_spinlock_unlock(&internals->lock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
__eth_bond_slave_remove_lock_free(uint8_t bonded_port_id, uint8_t slave_port_id)
|
||||
{
|
||||
struct bond_dev_private *internals;
|
||||
|
||||
int i, slave_idx = -1;
|
||||
|
||||
if (valid_slave_port_id(slave_port_id) != 0)
|
||||
goto err_del;
|
||||
return -1;
|
||||
|
||||
internals = rte_eth_devices[bonded_port_id].data->dev_private;
|
||||
|
||||
/* first remove from active slave list */
|
||||
for (i = 0; i < internals->active_slave_count; i++) {
|
||||
if (internals->active_slaves[i] == slave_port_id)
|
||||
pos = i;
|
||||
slave_idx = i;
|
||||
|
||||
/* shift active slaves up active array list */
|
||||
if (pos >= 0 && i < (internals->active_slave_count - 1))
|
||||
if (slave_idx >= 0 && i < (internals->active_slave_count - 1))
|
||||
internals->active_slaves[i] = internals->active_slaves[i+1];
|
||||
}
|
||||
|
||||
if (pos >= 0)
|
||||
if (slave_idx >= 0)
|
||||
internals->active_slave_count--;
|
||||
|
||||
pos = -1;
|
||||
/* now remove from slave list */
|
||||
for (i = 0; i < internals->slave_count; i++) {
|
||||
if (internals->slaves[i] == slave_port_id)
|
||||
pos = i;
|
||||
slave_idx = -1;
|
||||
/* now find in slave list */
|
||||
for (i = 0; i < internals->slave_count; i++)
|
||||
if (internals->slaves[i].port_id == slave_port_id) {
|
||||
slave_idx = i;
|
||||
break;
|
||||
}
|
||||
|
||||
/* shift slaves up list */
|
||||
if (pos >= 0 && i < internals->slave_count)
|
||||
internals->slaves[i] = internals->slaves[i+1];
|
||||
if (slave_idx < 0) {
|
||||
RTE_BOND_LOG(ERR, "Couldn't find slave in port list, slave count %d",
|
||||
internals->slave_count);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pos < 0)
|
||||
goto err_del;
|
||||
|
||||
/* Un-register link status change callback with bonded device pointer as
|
||||
* argument*/
|
||||
rte_eth_dev_callback_unregister(slave_port_id, RTE_ETH_EVENT_INTR_LSC,
|
||||
@ -422,13 +428,10 @@ rte_eth_bond_slave_remove(uint8_t bonded_port_id, uint8_t slave_port_id)
|
||||
&rte_eth_devices[bonded_port_id].data->port_id);
|
||||
|
||||
/* Restore original MAC address of slave device */
|
||||
slave_conf = slave_config_get(internals, slave_port_id);
|
||||
mac_address_set(&rte_eth_devices[slave_port_id],
|
||||
&(internals->slaves[slave_idx].persisted_mac_addr));
|
||||
|
||||
mac_address_set(&rte_eth_devices[slave_port_id], &(slave_conf->mac_addr));
|
||||
|
||||
slave_config_clear(internals, &rte_eth_devices[slave_port_id]);
|
||||
|
||||
internals->slave_count--;
|
||||
slave_remove(internals, &rte_eth_devices[slave_port_id]);
|
||||
|
||||
/* first slave in the active list will be the primary by default,
|
||||
* otherwise use first device in list */
|
||||
@ -436,7 +439,7 @@ rte_eth_bond_slave_remove(uint8_t bonded_port_id, uint8_t slave_port_id)
|
||||
if (internals->active_slave_count > 0)
|
||||
internals->current_primary_port = internals->active_slaves[0];
|
||||
else if (internals->slave_count > 0)
|
||||
internals->current_primary_port = internals->slaves[0];
|
||||
internals->current_primary_port = internals->slaves[0].port_id;
|
||||
else
|
||||
internals->primary_port = 0;
|
||||
}
|
||||
@ -454,12 +457,28 @@ rte_eth_bond_slave_remove(uint8_t bonded_port_id, uint8_t slave_port_id)
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
err_del:
|
||||
RTE_LOG(ERR, PMD,
|
||||
"Cannot remove slave device (not present in bonded device)\n");
|
||||
return -1;
|
||||
int
|
||||
rte_eth_bond_slave_remove(uint8_t bonded_port_id, uint8_t slave_port_id)
|
||||
{
|
||||
struct rte_eth_dev *bonded_eth_dev;
|
||||
struct bond_dev_private *internals;
|
||||
int retval;
|
||||
|
||||
if (valid_bonded_port_id(bonded_port_id) != 0)
|
||||
return -1;
|
||||
|
||||
bonded_eth_dev = &rte_eth_devices[bonded_port_id];
|
||||
internals = bonded_eth_dev->data->dev_private;
|
||||
|
||||
rte_spinlock_lock(&internals->lock);
|
||||
|
||||
retval = __eth_bond_slave_remove_lock_free(bonded_port_id, slave_port_id);
|
||||
|
||||
rte_spinlock_unlock(&internals->lock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
@ -524,6 +543,7 @@ int
|
||||
rte_eth_bond_slaves_get(uint8_t bonded_port_id, uint8_t slaves[], uint8_t len)
|
||||
{
|
||||
struct bond_dev_private *internals;
|
||||
int i;
|
||||
|
||||
if (valid_bonded_port_id(bonded_port_id) != 0)
|
||||
return -1;
|
||||
@ -536,10 +556,10 @@ rte_eth_bond_slaves_get(uint8_t bonded_port_id, uint8_t slaves[], uint8_t len)
|
||||
if (internals->slave_count > len)
|
||||
return -1;
|
||||
|
||||
memcpy(slaves, internals->slaves, internals->slave_count);
|
||||
for (i = 0; i < internals->slave_count; i++)
|
||||
slaves[i] = internals->slaves[i].port_id;
|
||||
|
||||
return internals->slave_count;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
@ -605,13 +625,13 @@ rte_eth_bond_mac_address_reset(uint8_t bonded_port_id)
|
||||
internals->user_defined_mac = 0;
|
||||
|
||||
if (internals->slave_count > 0) {
|
||||
struct slave_conf *conf;
|
||||
conf = slave_config_get(internals, internals->primary_port);
|
||||
|
||||
/* Set MAC Address of Bonded Device */
|
||||
if (mac_address_set(bonded_eth_dev, &conf->mac_addr) != 0)
|
||||
if (mac_address_set(bonded_eth_dev,
|
||||
&internals->slaves[internals->primary_port].persisted_mac_addr)
|
||||
!= 0) {
|
||||
RTE_BOND_LOG(ERR, "Failed to set MAC address on bonded device");
|
||||
return -1;
|
||||
|
||||
}
|
||||
/* Update all slave devices MAC addresses */
|
||||
return mac_address_slaves_update(bonded_eth_dev);
|
||||
}
|
||||
@ -654,3 +674,88 @@ rte_eth_bond_xmit_policy_get(uint8_t bonded_port_id)
|
||||
|
||||
return internals->balance_xmit_policy;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rte_eth_bond_link_monitoring_set(uint8_t bonded_port_id, uint32_t internal_ms)
|
||||
{
|
||||
struct bond_dev_private *internals;
|
||||
|
||||
if (valid_bonded_port_id(bonded_port_id) != 0)
|
||||
return -1;
|
||||
|
||||
internals = rte_eth_devices[bonded_port_id].data->dev_private;
|
||||
internals->link_status_polling_interval_ms = internal_ms;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rte_eth_bond_link_monitoring_get(uint8_t bonded_port_id)
|
||||
{
|
||||
struct bond_dev_private *internals;
|
||||
|
||||
if (valid_bonded_port_id(bonded_port_id) != 0)
|
||||
return -1;
|
||||
|
||||
internals = rte_eth_devices[bonded_port_id].data->dev_private;
|
||||
|
||||
return internals->link_status_polling_interval_ms;
|
||||
}
|
||||
|
||||
int
|
||||
rte_eth_bond_link_down_prop_delay_set(uint8_t bonded_port_id, uint32_t delay_ms)
|
||||
|
||||
{
|
||||
struct bond_dev_private *internals;
|
||||
|
||||
if (valid_bonded_port_id(bonded_port_id) != 0)
|
||||
return -1;
|
||||
|
||||
internals = rte_eth_devices[bonded_port_id].data->dev_private;
|
||||
internals->link_down_delay_ms = delay_ms;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rte_eth_bond_link_down_prop_delay_get(uint8_t bonded_port_id)
|
||||
{
|
||||
struct bond_dev_private *internals;
|
||||
|
||||
if (valid_bonded_port_id(bonded_port_id) != 0)
|
||||
return -1;
|
||||
|
||||
internals = rte_eth_devices[bonded_port_id].data->dev_private;
|
||||
|
||||
return internals->link_down_delay_ms;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rte_eth_bond_link_up_prop_delay_set(uint8_t bonded_port_id, uint32_t delay_ms)
|
||||
|
||||
{
|
||||
struct bond_dev_private *internals;
|
||||
|
||||
if (valid_bonded_port_id(bonded_port_id) != 0)
|
||||
return -1;
|
||||
|
||||
internals = rte_eth_devices[bonded_port_id].data->dev_private;
|
||||
internals->link_up_delay_ms = delay_ms;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rte_eth_bond_link_up_prop_delay_get(uint8_t bonded_port_id)
|
||||
{
|
||||
struct bond_dev_private *internals;
|
||||
|
||||
if (valid_bonded_port_id(bonded_port_id) != 0)
|
||||
return -1;
|
||||
|
||||
internals = rte_eth_devices[bonded_port_id].data->dev_private;
|
||||
|
||||
return internals->link_up_delay_ms;
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ parse_port_id(const char *port_str)
|
||||
}
|
||||
|
||||
if (port_id < 0 || port_id > RTE_MAX_ETHPORTS) {
|
||||
RTE_LOG(ERR, PMD, "Invalid slave port value (%s) specified.\n",
|
||||
RTE_BOND_LOG(ERR, "Slave port specified (%s) outside expected range",
|
||||
port_str);
|
||||
return -1;
|
||||
}
|
||||
@ -138,9 +138,10 @@ bond_ethdev_parse_slave_port_kvarg(const char *key __rte_unused,
|
||||
|
||||
if (strcmp(key, PMD_BOND_SLAVE_PORT_KVARG) == 0) {
|
||||
int port_id = parse_port_id(value);
|
||||
if (port_id < 0)
|
||||
if (port_id < 0) {
|
||||
RTE_BOND_LOG(ERR, "Invalid slave port value (%s) specified", value);
|
||||
return -1;
|
||||
else
|
||||
} else
|
||||
slave_ports->slaves[slave_ports->slave_count++] =
|
||||
(uint8_t)port_id;
|
||||
}
|
||||
@ -174,6 +175,7 @@ bond_ethdev_parse_slave_mode_kvarg(const char *key __rte_unused,
|
||||
#endif
|
||||
return 0;
|
||||
default:
|
||||
RTE_BOND_LOG(ERR, "Invalid slave mode value (%s) specified", value);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -252,3 +254,23 @@ bond_ethdev_parse_bond_mac_addr_kvarg(const char *key __rte_unused,
|
||||
/* Parse MAC */
|
||||
return cmdline_parse_etheraddr(NULL, value, extra_args);
|
||||
}
|
||||
|
||||
int
|
||||
bond_ethdev_parse_time_ms_kvarg(const char *key __rte_unused,
|
||||
const char *value, void *extra_args)
|
||||
{
|
||||
uint32_t time_ms;
|
||||
char *endptr;
|
||||
|
||||
if (value == NULL || extra_args == NULL)
|
||||
return -1;
|
||||
|
||||
errno = 0;
|
||||
time_ms = (uint32_t)strtol(value, &endptr, 10);
|
||||
if (*endptr != 0 || errno != 0)
|
||||
return -1;
|
||||
|
||||
*(uint32_t *)extra_args = time_ms;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <rte_devargs.h>
|
||||
#include <rte_kvargs.h>
|
||||
#include <rte_dev.h>
|
||||
#include <rte_alarm.h>
|
||||
|
||||
#include "rte_eth_bond.h"
|
||||
#include "rte_eth_bond_private.h"
|
||||
@ -457,16 +458,16 @@ mac_address_set(struct rte_eth_dev *eth_dev, struct ether_addr *new_mac_addr)
|
||||
mac_addr = eth_dev->data->mac_addrs;
|
||||
|
||||
if (eth_dev == NULL) {
|
||||
RTE_LOG(ERR, PMD, "%s: NULL pointer eth_dev specified\n", __func__);
|
||||
RTE_BOND_LOG(ERR, "NULL pointer eth_dev specified");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (new_mac_addr == NULL) {
|
||||
RTE_LOG(ERR, PMD, "%s: NULL pointer MAC specified\n", __func__);
|
||||
RTE_BOND_LOG(ERR, "NULL pointer MAC specified");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* if new MAC is different to current MAC then update */
|
||||
/* If new MAC is different to current MAC then update */
|
||||
if (memcmp(mac_addr, new_mac_addr, sizeof(*mac_addr)) != 0)
|
||||
memcpy(mac_addr, new_mac_addr, sizeof(*mac_addr));
|
||||
|
||||
@ -490,11 +491,10 @@ mac_address_slaves_update(struct rte_eth_dev *bonded_eth_dev)
|
||||
case BONDING_MODE_BROADCAST:
|
||||
#endif
|
||||
for (i = 0; i < internals->slave_count; i++) {
|
||||
if (mac_address_set(&rte_eth_devices[internals->slaves[i]],
|
||||
if (mac_address_set(&rte_eth_devices[internals->slaves[i].port_id],
|
||||
bonded_eth_dev->data->mac_addrs)) {
|
||||
RTE_LOG(ERR, PMD,
|
||||
"%s: Failed to update port Id %d MAC address\n",
|
||||
__func__, internals->slaves[i]);
|
||||
RTE_BOND_LOG(ERR, "Failed to update port Id %d MAC address",
|
||||
internals->slaves[i].port_id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -502,23 +502,20 @@ mac_address_slaves_update(struct rte_eth_dev *bonded_eth_dev)
|
||||
case BONDING_MODE_ACTIVE_BACKUP:
|
||||
default:
|
||||
for (i = 0; i < internals->slave_count; i++) {
|
||||
if (internals->slaves[i] == internals->current_primary_port) {
|
||||
if (internals->slaves[i].port_id ==
|
||||
internals->current_primary_port) {
|
||||
if (mac_address_set(&rte_eth_devices[internals->primary_port],
|
||||
bonded_eth_dev->data->mac_addrs)) {
|
||||
RTE_LOG(ERR, PMD,
|
||||
"%s: Failed to update port Id %d MAC address\n",
|
||||
__func__, internals->current_primary_port);
|
||||
RTE_BOND_LOG(ERR, "Failed to update port Id %d MAC address",
|
||||
internals->current_primary_port);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
struct slave_conf *conf =
|
||||
slave_config_get(internals, internals->slaves[i]);
|
||||
|
||||
if (mac_address_set(&rte_eth_devices[internals->slaves[i]],
|
||||
&conf->mac_addr)) {
|
||||
RTE_LOG(ERR, PMD,
|
||||
"%s: Failed to update port Id %d MAC address\n",
|
||||
__func__, internals->slaves[i]);
|
||||
|
||||
if (mac_address_set(
|
||||
&rte_eth_devices[internals->slaves[i].port_id],
|
||||
&internals->slaves[i].persisted_mac_addr)) {
|
||||
RTE_BOND_LOG(ERR, "Failed to update port Id %d MAC address",
|
||||
internals->slaves[i].port_id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -570,34 +567,39 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev,
|
||||
struct bond_rx_queue *bd_rx_q;
|
||||
struct bond_tx_queue *bd_tx_q;
|
||||
|
||||
int q_id;
|
||||
int errval, q_id;
|
||||
|
||||
/* Stop slave */
|
||||
rte_eth_dev_stop(slave_eth_dev->data->port_id);
|
||||
|
||||
/* Enable interrupts on slave device */
|
||||
slave_eth_dev->data->dev_conf.intr_conf.lsc = 1;
|
||||
/* Enable interrupts on slave device if supported */
|
||||
if (slave_eth_dev->driver->pci_drv.drv_flags & RTE_PCI_DRV_INTR_LSC)
|
||||
slave_eth_dev->data->dev_conf.intr_conf.lsc = 1;
|
||||
|
||||
if (rte_eth_dev_configure(slave_eth_dev->data->port_id,
|
||||
/* Configure device */
|
||||
errval = rte_eth_dev_configure(slave_eth_dev->data->port_id,
|
||||
bonded_eth_dev->data->nb_rx_queues,
|
||||
bonded_eth_dev->data->nb_tx_queues,
|
||||
&(slave_eth_dev->data->dev_conf)) != 0) {
|
||||
RTE_LOG(ERR, PMD, "Cannot configure slave device: port=%u\n",
|
||||
slave_eth_dev->data->port_id);
|
||||
return -1;
|
||||
&(slave_eth_dev->data->dev_conf));
|
||||
if (errval != 0) {
|
||||
RTE_BOND_LOG(ERR, "Cannot configure slave device: port %u , err (%d)",
|
||||
slave_eth_dev->data->port_id, errval);
|
||||
return errval;
|
||||
}
|
||||
|
||||
/* Setup Rx Queues */
|
||||
for (q_id = 0; q_id < bonded_eth_dev->data->nb_rx_queues; q_id++) {
|
||||
bd_rx_q = (struct bond_rx_queue *)bonded_eth_dev->data->rx_queues[q_id];
|
||||
|
||||
if (rte_eth_rx_queue_setup(slave_eth_dev->data->port_id, q_id,
|
||||
errval = rte_eth_rx_queue_setup(slave_eth_dev->data->port_id, q_id,
|
||||
bd_rx_q->nb_rx_desc,
|
||||
rte_eth_dev_socket_id(slave_eth_dev->data->port_id),
|
||||
&(bd_rx_q->rx_conf), bd_rx_q->mb_pool) != 0) {
|
||||
RTE_LOG(ERR, PMD, "rte_eth_rx_queue_setup: port=%d queue_id %d\n",
|
||||
slave_eth_dev->data->port_id, q_id);
|
||||
return -1;
|
||||
&(bd_rx_q->rx_conf), bd_rx_q->mb_pool);
|
||||
if (errval != 0) {
|
||||
RTE_BOND_LOG(ERR,
|
||||
"rte_eth_rx_queue_setup: port=%d queue_id %d, err (%d)",
|
||||
slave_eth_dev->data->port_id, q_id, errval);
|
||||
return errval;
|
||||
}
|
||||
}
|
||||
|
||||
@ -605,69 +607,77 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev,
|
||||
for (q_id = 0; q_id < bonded_eth_dev->data->nb_tx_queues; q_id++) {
|
||||
bd_tx_q = (struct bond_tx_queue *)bonded_eth_dev->data->tx_queues[q_id];
|
||||
|
||||
if (rte_eth_tx_queue_setup(slave_eth_dev->data->port_id, q_id,
|
||||
errval = rte_eth_tx_queue_setup(slave_eth_dev->data->port_id, q_id,
|
||||
bd_tx_q->nb_tx_desc,
|
||||
rte_eth_dev_socket_id(slave_eth_dev->data->port_id),
|
||||
&bd_tx_q->tx_conf) != 0) {
|
||||
RTE_LOG(ERR, PMD, "rte_eth_tx_queue_setup: port=%d queue_id %d\n",
|
||||
slave_eth_dev->data->port_id, q_id);
|
||||
return -1;
|
||||
&bd_tx_q->tx_conf);
|
||||
if (errval != 0) {
|
||||
RTE_BOND_LOG(ERR,
|
||||
"rte_eth_tx_queue_setup: port=%d queue_id %d, err (%d)",
|
||||
slave_eth_dev->data->port_id, q_id, errval);
|
||||
return errval;
|
||||
}
|
||||
}
|
||||
|
||||
/* Start device */
|
||||
if (rte_eth_dev_start(slave_eth_dev->data->port_id) != 0) {
|
||||
RTE_LOG(ERR, PMD, "rte_eth_dev_start: port=%u\n",
|
||||
slave_eth_dev->data->port_id);
|
||||
errval = rte_eth_dev_start(slave_eth_dev->data->port_id);
|
||||
if (errval != 0) {
|
||||
RTE_BOND_LOG(ERR, "rte_eth_dev_start: port=%u, err (%d)",
|
||||
slave_eth_dev->data->port_id, errval);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct slave_conf *
|
||||
slave_config_get(struct bond_dev_private *internals, uint8_t slave_port_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < internals->slave_count; i++) {
|
||||
if (internals->presisted_slaves_conf[i].port_id == slave_port_id)
|
||||
return &internals->presisted_slaves_conf[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
slave_config_clear(struct bond_dev_private *internals,
|
||||
slave_remove(struct bond_dev_private *internals,
|
||||
struct rte_eth_dev *slave_eth_dev)
|
||||
{
|
||||
int i, found = 0;
|
||||
|
||||
for (i = 0; i < internals->slave_count; i++) {
|
||||
if (internals->presisted_slaves_conf[i].port_id ==
|
||||
slave_eth_dev->data->port_id) {
|
||||
if (internals->slaves[i].port_id == slave_eth_dev->data->port_id)
|
||||
found = 1;
|
||||
memset(&internals->presisted_slaves_conf[i], 0,
|
||||
sizeof(internals->presisted_slaves_conf[i]));
|
||||
}
|
||||
if (found && i < (internals->slave_count - 1)) {
|
||||
memcpy(&internals->presisted_slaves_conf[i],
|
||||
&internals->presisted_slaves_conf[i+1],
|
||||
sizeof(internals->presisted_slaves_conf[i]));
|
||||
}
|
||||
|
||||
if (found && i < (internals->slave_count - 1))
|
||||
memcpy(&internals->slaves[i], &internals->slaves[i+1],
|
||||
sizeof(internals->slaves[i]));
|
||||
}
|
||||
|
||||
internals->slave_count--;
|
||||
}
|
||||
|
||||
static void
|
||||
bond_ethdev_slave_link_status_change_monitor(void *cb_arg);
|
||||
|
||||
void
|
||||
slave_config_store(struct bond_dev_private *internals,
|
||||
slave_add(struct bond_dev_private *internals,
|
||||
struct rte_eth_dev *slave_eth_dev)
|
||||
{
|
||||
struct slave_conf *presisted_slave_conf =
|
||||
&internals->presisted_slaves_conf[internals->slave_count];
|
||||
struct bond_slave_details *slave_details =
|
||||
&internals->slaves[internals->slave_count];
|
||||
|
||||
presisted_slave_conf->port_id = slave_eth_dev->data->port_id;
|
||||
slave_details->port_id = slave_eth_dev->data->port_id;
|
||||
slave_details->last_link_status = 0;
|
||||
|
||||
memcpy(&(presisted_slave_conf->mac_addr), slave_eth_dev->data->mac_addrs,
|
||||
/* If slave device doesn't support interrupts then we need to enabled
|
||||
* polling to monitor link status */
|
||||
if (!(slave_eth_dev->pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)) {
|
||||
slave_details->link_status_poll_enabled = 1;
|
||||
|
||||
if (!internals->link_status_polling_enabled) {
|
||||
internals->link_status_polling_enabled = 1;
|
||||
|
||||
rte_eal_alarm_set(internals->link_status_polling_interval_ms * 1000,
|
||||
bond_ethdev_slave_link_status_change_monitor,
|
||||
(void *)&rte_eth_devices[internals->port_id]);
|
||||
}
|
||||
}
|
||||
|
||||
slave_details->link_status_wait_to_complete = 0;
|
||||
|
||||
memcpy(&(slave_details->persisted_mac_addr), slave_eth_dev->data->mac_addrs,
|
||||
sizeof(struct ether_addr));
|
||||
}
|
||||
|
||||
@ -698,31 +708,33 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev)
|
||||
|
||||
/* slave eth dev will be started by bonded device */
|
||||
if (valid_bonded_ethdev(eth_dev)) {
|
||||
RTE_LOG(ERR, PMD,
|
||||
"%s: user tried to explicitly start a slave eth_dev (%d) of the bonded eth_dev\n",
|
||||
__func__, eth_dev->data->port_id);
|
||||
RTE_BOND_LOG(ERR, "User tried to explicitly start a slave eth_dev (%d)",
|
||||
eth_dev->data->port_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
eth_dev->data->dev_link.link_status = 1;
|
||||
eth_dev->data->dev_link.link_status = 0;
|
||||
eth_dev->data->dev_started = 1;
|
||||
|
||||
internals = eth_dev->data->dev_private;
|
||||
|
||||
if (internals->slave_count == 0) {
|
||||
RTE_LOG(ERR, PMD,
|
||||
"%s: Cannot start port since there are no slave devices\n",
|
||||
__func__);
|
||||
RTE_BOND_LOG(ERR, "Cannot start port since there are no slave devices");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (internals->user_defined_mac == 0) {
|
||||
struct slave_conf *conf = slave_config_get(internals,
|
||||
internals->primary_port);
|
||||
struct ether_addr *new_mac_addr = NULL;
|
||||
|
||||
if (mac_address_set(eth_dev, &(conf->mac_addr)) != 0) {
|
||||
RTE_LOG(ERR, PMD,
|
||||
"bonded port (%d) failed to update mac address",
|
||||
for (i = 0; i < internals->slave_count; i++)
|
||||
if (internals->slaves[i].port_id == internals->primary_port)
|
||||
new_mac_addr = &internals->slaves[i].persisted_mac_addr;
|
||||
|
||||
if (new_mac_addr == NULL)
|
||||
return -1;
|
||||
|
||||
if (mac_address_set(eth_dev, new_mac_addr) != 0) {
|
||||
RTE_BOND_LOG(ERR, "bonded port (%d) failed to update MAC address",
|
||||
eth_dev->data->port_id);
|
||||
return -1;
|
||||
}
|
||||
@ -738,11 +750,11 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev)
|
||||
|
||||
/* Reconfigure each slave device if starting bonded device */
|
||||
for (i = 0; i < internals->slave_count; i++) {
|
||||
if (slave_configure(eth_dev, &(rte_eth_devices[internals->slaves[i]]))
|
||||
!= 0) {
|
||||
RTE_LOG(ERR, PMD, "bonded port "
|
||||
"(%d) failed to reconfigure slave device (%d)\n)",
|
||||
eth_dev->data->port_id, internals->slaves[i]);
|
||||
if (slave_configure(eth_dev,
|
||||
&(rte_eth_devices[internals->slaves[i].port_id])) != 0) {
|
||||
RTE_BOND_LOG(ERR,
|
||||
"bonded port (%d) failed to reconfigure slave device (%d)",
|
||||
eth_dev->data->port_id, internals->slaves[i].port_id);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -759,6 +771,7 @@ bond_ethdev_stop(struct rte_eth_dev *eth_dev)
|
||||
struct bond_dev_private *internals = eth_dev->data->dev_private;
|
||||
|
||||
internals->active_slave_count = 0;
|
||||
internals->link_status_polling_enabled = 0;
|
||||
|
||||
eth_dev->data->dev_link.link_status = 0;
|
||||
eth_dev->data->dev_started = 0;
|
||||
@ -852,6 +865,65 @@ bond_ethdev_tx_queue_release(void *queue)
|
||||
rte_free(queue);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
bond_ethdev_slave_link_status_change_monitor(void *cb_arg)
|
||||
{
|
||||
struct rte_eth_dev *bonded_ethdev, *slave_ethdev;
|
||||
struct bond_dev_private *internals;
|
||||
|
||||
/* Default value for polling slave found is true as we don't want to
|
||||
* disable the polling thread if we cannot get the lock */
|
||||
int i, polling_slave_found = 1;
|
||||
|
||||
if (cb_arg == NULL)
|
||||
return;
|
||||
|
||||
bonded_ethdev = (struct rte_eth_dev *)cb_arg;
|
||||
internals = (struct bond_dev_private *)bonded_ethdev->data->dev_private;
|
||||
|
||||
if (!bonded_ethdev->data->dev_started ||
|
||||
!internals->link_status_polling_enabled)
|
||||
return;
|
||||
|
||||
/* If device is currently being configured then don't check slaves link
|
||||
* status, wait until next period */
|
||||
if (rte_spinlock_trylock(&internals->lock)) {
|
||||
if (internals->slave_count > 0)
|
||||
polling_slave_found = 0;
|
||||
|
||||
for (i = 0; i < internals->slave_count; i++) {
|
||||
if (!internals->slaves[i].link_status_poll_enabled)
|
||||
continue;
|
||||
|
||||
slave_ethdev = &rte_eth_devices[internals->slaves[i].port_id];
|
||||
polling_slave_found = 1;
|
||||
|
||||
/* Update slave link status */
|
||||
(*slave_ethdev->dev_ops->link_update)(slave_ethdev,
|
||||
internals->slaves[i].link_status_wait_to_complete);
|
||||
|
||||
/* if link status has changed since last checked then call lsc
|
||||
* event callback */
|
||||
if (slave_ethdev->data->dev_link.link_status !=
|
||||
internals->slaves[i].last_link_status) {
|
||||
internals->slaves[i].last_link_status =
|
||||
slave_ethdev->data->dev_link.link_status;
|
||||
|
||||
bond_ethdev_lsc_event_callback(internals->slaves[i].port_id,
|
||||
RTE_ETH_EVENT_INTR_LSC,
|
||||
&bonded_ethdev->data->port_id);
|
||||
}
|
||||
}
|
||||
rte_spinlock_unlock(&internals->lock);
|
||||
}
|
||||
|
||||
if (polling_slave_found)
|
||||
/* Set alarm to continue monitoring link status of slave ethdev's */
|
||||
rte_eal_alarm_set(internals->link_status_polling_interval_ms * 1000,
|
||||
bond_ethdev_slave_link_status_change_monitor, cb_arg);
|
||||
}
|
||||
|
||||
static int
|
||||
bond_ethdev_link_update(struct rte_eth_dev *bonded_eth_dev,
|
||||
int wait_to_complete)
|
||||
@ -895,7 +967,7 @@ bond_ethdev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
|
||||
memset(stats, 0, sizeof(*stats));
|
||||
|
||||
for (i = 0; i < internals->slave_count; i++) {
|
||||
rte_eth_stats_get(internals->slaves[i], &slave_stats);
|
||||
rte_eth_stats_get(internals->slaves[i].port_id, &slave_stats);
|
||||
|
||||
stats->ipackets += slave_stats.ipackets;
|
||||
stats->opackets += slave_stats.opackets;
|
||||
@ -921,7 +993,7 @@ bond_ethdev_stats_reset(struct rte_eth_dev *dev)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < internals->slave_count; i++)
|
||||
rte_eth_stats_reset(internals->slaves[i]);
|
||||
rte_eth_stats_reset(internals->slaves[i].port_id);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -940,7 +1012,7 @@ bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev)
|
||||
case BONDING_MODE_BROADCAST:
|
||||
#endif
|
||||
for (i = 0; i < internals->slave_count; i++)
|
||||
rte_eth_promiscuous_enable(internals->slaves[i]);
|
||||
rte_eth_promiscuous_enable(internals->slaves[i].port_id);
|
||||
break;
|
||||
/* Promiscuous mode is propagated only to primary slave */
|
||||
case BONDING_MODE_ACTIVE_BACKUP:
|
||||
@ -966,7 +1038,7 @@ bond_ethdev_promiscuous_disable(struct rte_eth_dev *dev)
|
||||
case BONDING_MODE_BROADCAST:
|
||||
#endif
|
||||
for (i = 0; i < internals->slave_count; i++)
|
||||
rte_eth_promiscuous_disable(internals->slaves[i]);
|
||||
rte_eth_promiscuous_disable(internals->slaves[i].port_id);
|
||||
break;
|
||||
/* Promiscuous mode is propagated only to primary slave */
|
||||
case BONDING_MODE_ACTIVE_BACKUP:
|
||||
@ -975,6 +1047,16 @@ bond_ethdev_promiscuous_disable(struct rte_eth_dev *dev)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bond_ethdev_delayed_lsc_propagation(void *arg)
|
||||
{
|
||||
if (arg == NULL)
|
||||
return;
|
||||
|
||||
_rte_eth_dev_callback_process((struct rte_eth_dev *)arg,
|
||||
RTE_ETH_EVENT_INTR_LSC);
|
||||
}
|
||||
|
||||
void
|
||||
bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
|
||||
void *param)
|
||||
@ -1003,7 +1085,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
|
||||
|
||||
/* verify that port_id is a valid slave of bonded port */
|
||||
for (i = 0; i < internals->slave_count; i++) {
|
||||
if (internals->slaves[i] == port_id) {
|
||||
if (internals->slaves[i].port_id == port_id) {
|
||||
valid_slave = 1;
|
||||
break;
|
||||
}
|
||||
@ -1072,8 +1154,32 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum rte_eth_event_type type,
|
||||
}
|
||||
}
|
||||
|
||||
if (lsc_flag)
|
||||
_rte_eth_dev_callback_process(bonded_eth_dev, RTE_ETH_EVENT_INTR_LSC);
|
||||
if (lsc_flag) {
|
||||
/* Cancel any possible outstanding interrupts if delays are enabled */
|
||||
if (internals->link_up_delay_ms > 0 ||
|
||||
internals->link_down_delay_ms > 0)
|
||||
rte_eal_alarm_cancel(bond_ethdev_delayed_lsc_propagation,
|
||||
bonded_eth_dev);
|
||||
|
||||
if (bonded_eth_dev->data->dev_link.link_status) {
|
||||
if (internals->link_up_delay_ms > 0)
|
||||
rte_eal_alarm_set(internals->link_up_delay_ms * 1000,
|
||||
bond_ethdev_delayed_lsc_propagation,
|
||||
(void *)bonded_eth_dev);
|
||||
else
|
||||
_rte_eth_dev_callback_process(bonded_eth_dev,
|
||||
RTE_ETH_EVENT_INTR_LSC);
|
||||
|
||||
} else {
|
||||
if (internals->link_down_delay_ms > 0)
|
||||
rte_eal_alarm_set(internals->link_down_delay_ms * 1000,
|
||||
bond_ethdev_delayed_lsc_propagation,
|
||||
(void *)bonded_eth_dev);
|
||||
else
|
||||
_rte_eth_dev_callback_process(bonded_eth_dev,
|
||||
RTE_ETH_EVENT_INTR_LSC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct eth_dev_ops default_dev_ops = {
|
||||
@ -1223,8 +1329,8 @@ bond_ethdev_configure(struct rte_eth_dev *dev)
|
||||
}
|
||||
} else if (arg_count > 1) {
|
||||
RTE_LOG(ERR, EAL,
|
||||
"Transmit policy can be specified only once for bonded device %s\n",
|
||||
name);
|
||||
"Transmit policy can be specified only once for bonded device"
|
||||
" %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1266,8 +1372,8 @@ bond_ethdev_configure(struct rte_eth_dev *dev)
|
||||
&bond_ethdev_parse_primary_slave_port_id_kvarg,
|
||||
&primary_slave_port_id) < 0) {
|
||||
RTE_LOG(INFO, EAL,
|
||||
"Invalid primary slave port id specified for bonded device %s\n",
|
||||
name);
|
||||
"Invalid primary slave port id specified for bonded device"
|
||||
" %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1281,8 +1387,97 @@ bond_ethdev_configure(struct rte_eth_dev *dev)
|
||||
}
|
||||
} else if (arg_count > 1) {
|
||||
RTE_LOG(INFO, EAL,
|
||||
"Primary slave can be specified only once for bonded device %s\n",
|
||||
name);
|
||||
"Primary slave can be specified only once for bonded device"
|
||||
" %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Parse link status monitor polling interval */
|
||||
arg_count = rte_kvargs_count(kvlist, PMD_BOND_LSC_POLL_PERIOD_KVARG);
|
||||
if (arg_count == 1) {
|
||||
uint32_t lsc_poll_interval_ms;
|
||||
|
||||
if (rte_kvargs_process(kvlist,
|
||||
PMD_BOND_LSC_POLL_PERIOD_KVARG,
|
||||
&bond_ethdev_parse_time_ms_kvarg,
|
||||
&lsc_poll_interval_ms) < 0) {
|
||||
RTE_LOG(INFO, EAL,
|
||||
"Invalid lsc polling interval value specified for bonded"
|
||||
" device %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rte_eth_bond_link_monitoring_set(port_id, lsc_poll_interval_ms)
|
||||
!= 0) {
|
||||
RTE_LOG(ERR, EAL,
|
||||
"Failed to set lsc monitor polling interval (%u ms) on"
|
||||
" bonded device %s\n", lsc_poll_interval_ms, name);
|
||||
return -1;
|
||||
}
|
||||
} else if (arg_count > 1) {
|
||||
RTE_LOG(INFO, EAL,
|
||||
"LSC polling interval can be specified only once for bonded"
|
||||
" device %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Parse link up interrupt propagation delay */
|
||||
arg_count = rte_kvargs_count(kvlist, PMD_BOND_LINK_UP_PROP_DELAY_KVARG);
|
||||
if (arg_count == 1) {
|
||||
uint32_t link_up_delay_ms;
|
||||
|
||||
if (rte_kvargs_process(kvlist,
|
||||
PMD_BOND_LINK_UP_PROP_DELAY_KVARG,
|
||||
&bond_ethdev_parse_time_ms_kvarg,
|
||||
&link_up_delay_ms) < 0) {
|
||||
RTE_LOG(INFO, EAL,
|
||||
"Invalid link up propagation delay value specified for"
|
||||
" bonded device %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set balance mode transmit policy*/
|
||||
if (rte_eth_bond_link_up_prop_delay_set(port_id, link_up_delay_ms)
|
||||
!= 0) {
|
||||
RTE_LOG(ERR, EAL,
|
||||
"Failed to set link up propagation delay (%u ms) on bonded"
|
||||
" device %s\n", link_up_delay_ms, name);
|
||||
return -1;
|
||||
}
|
||||
} else if (arg_count > 1) {
|
||||
RTE_LOG(INFO, EAL,
|
||||
"Link up propagation delay can be specified only once for"
|
||||
" bonded device %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Parse link down interrupt propagation delay */
|
||||
arg_count = rte_kvargs_count(kvlist, PMD_BOND_LINK_DOWN_PROP_DELAY_KVARG);
|
||||
if (arg_count == 1) {
|
||||
uint32_t link_down_delay_ms;
|
||||
|
||||
if (rte_kvargs_process(kvlist,
|
||||
PMD_BOND_LINK_DOWN_PROP_DELAY_KVARG,
|
||||
&bond_ethdev_parse_time_ms_kvarg,
|
||||
&link_down_delay_ms) < 0) {
|
||||
RTE_LOG(INFO, EAL,
|
||||
"Invalid link down propagation delay value specified for"
|
||||
" bonded device %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set balance mode transmit policy*/
|
||||
if (rte_eth_bond_link_down_prop_delay_set(port_id, link_down_delay_ms)
|
||||
!= 0) {
|
||||
RTE_LOG(ERR, EAL,
|
||||
"Failed to set link down propagation delay (%u ms) on"
|
||||
" bonded device %s\n", link_down_delay_ms, name);
|
||||
return -1;
|
||||
}
|
||||
} else if (arg_count > 1) {
|
||||
RTE_LOG(INFO, EAL,
|
||||
"Link down propagation delay can be specified only once for"
|
||||
" bonded device %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -39,20 +39,27 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <rte_ethdev.h>
|
||||
#include <rte_spinlock.h>
|
||||
|
||||
#include "rte_eth_bond.h"
|
||||
|
||||
#define PMD_BOND_SLAVE_PORT_KVARG ("slave")
|
||||
#define PMD_BOND_PRIMARY_SLAVE_KVARG ("primary")
|
||||
#define PMD_BOND_MODE_KVARG ("mode")
|
||||
#define PMD_BOND_XMIT_POLICY_KVARG ("xmit_policy")
|
||||
#define PMD_BOND_SOCKET_ID_KVARG ("socket_id")
|
||||
#define PMD_BOND_MAC_ADDR_KVARG ("mac")
|
||||
#define PMD_BOND_SLAVE_PORT_KVARG ("slave")
|
||||
#define PMD_BOND_PRIMARY_SLAVE_KVARG ("primary")
|
||||
#define PMD_BOND_MODE_KVARG ("mode")
|
||||
#define PMD_BOND_XMIT_POLICY_KVARG ("xmit_policy")
|
||||
#define PMD_BOND_SOCKET_ID_KVARG ("socket_id")
|
||||
#define PMD_BOND_MAC_ADDR_KVARG ("mac")
|
||||
#define PMD_BOND_LSC_POLL_PERIOD_KVARG ("lsc_poll_period_ms")
|
||||
#define PMD_BOND_LINK_UP_PROP_DELAY_KVARG ("up_delay")
|
||||
#define PMD_BOND_LINK_DOWN_PROP_DELAY_KVARG ("down_delay")
|
||||
|
||||
#define PMD_BOND_XMIT_POLICY_LAYER2_KVARG ("l2")
|
||||
#define PMD_BOND_XMIT_POLICY_LAYER23_KVARG ("l23")
|
||||
#define PMD_BOND_XMIT_POLICY_LAYER34_KVARG ("l34")
|
||||
|
||||
#define RTE_BOND_LOG(lvl, msg, ...) \
|
||||
RTE_LOG(lvl, PMD, "%s(%d) - " msg "\n", __func__, __LINE__, ##__VA_ARGS__)
|
||||
|
||||
extern const char *pmd_bond_init_valid_arguments[];
|
||||
|
||||
extern const char *driver_name;
|
||||
@ -82,27 +89,36 @@ struct bond_tx_queue {
|
||||
/**< Copy of TX configuration structure for queue */
|
||||
};
|
||||
|
||||
/** Persisted Slave Configuration Structure */
|
||||
struct slave_conf {
|
||||
uint8_t port_id;
|
||||
/**< Port Id of slave eth_dev */
|
||||
struct ether_addr mac_addr;
|
||||
/**< Slave eth_dev original MAC address */
|
||||
};
|
||||
|
||||
/** Bonded slave devices structure */
|
||||
struct bond_ethdev_slave_ports {
|
||||
uint8_t slaves[RTE_MAX_ETHPORTS]; /**< Slave port id array */
|
||||
uint8_t slave_count; /**< Number of slaves */
|
||||
};
|
||||
|
||||
struct bond_slave_details {
|
||||
uint8_t port_id;
|
||||
|
||||
uint8_t link_status_poll_enabled;
|
||||
uint8_t link_status_wait_to_complete;
|
||||
uint8_t last_link_status;
|
||||
|
||||
/**< Port Id of slave eth_dev */
|
||||
struct ether_addr persisted_mac_addr;
|
||||
};
|
||||
|
||||
/** Link Bonding PMD device private configuration Structure */
|
||||
struct bond_dev_private {
|
||||
uint8_t port_id; /**< Port Id of Bonded Port */
|
||||
uint8_t mode; /**< Link Bonding Mode */
|
||||
|
||||
rte_spinlock_t lock;
|
||||
|
||||
uint8_t primary_port; /**< Primary Slave Port */
|
||||
uint8_t current_primary_port; /**< Primary Slave Port */
|
||||
uint8_t user_defined_primary_port;
|
||||
/**< Flag for whether primary port is user defined or not */
|
||||
|
||||
uint8_t balance_xmit_policy;
|
||||
/**< Transmit policy - l2 / l23 / l34 for operation in balance mode */
|
||||
uint8_t user_defined_mac;
|
||||
@ -110,19 +126,23 @@ struct bond_dev_private {
|
||||
uint8_t promiscuous_en;
|
||||
/**< Enabled/disable promiscuous mode on slave devices */
|
||||
uint8_t link_props_set;
|
||||
/**< Bonded eth_dev link properties set */
|
||||
/**< flag to denote if the link properties are set */
|
||||
|
||||
uint8_t link_status_polling_enabled;
|
||||
uint32_t link_status_polling_interval_ms;
|
||||
|
||||
uint32_t link_down_delay_ms;
|
||||
uint32_t link_up_delay_ms;
|
||||
|
||||
uint16_t nb_rx_queues; /**< Total number of rx queues */
|
||||
uint16_t nb_tx_queues; /**< Total number of tx queues*/
|
||||
|
||||
uint8_t slave_count; /**< Number of active slaves */
|
||||
uint8_t active_slave_count; /**< Number of slaves */
|
||||
|
||||
uint8_t active_slave_count; /**< Number of active slaves */
|
||||
uint8_t active_slaves[RTE_MAX_ETHPORTS]; /**< Active slave list */
|
||||
uint8_t slaves[RTE_MAX_ETHPORTS]; /**< Slave list */
|
||||
|
||||
/** Persisted configuration of slaves */
|
||||
struct slave_conf presisted_slaves_conf[RTE_MAX_ETHPORTS];
|
||||
uint8_t slave_count; /**< Number of bonded slaves */
|
||||
struct bond_slave_details slaves[RTE_MAX_ETHPORTS];
|
||||
/**< Arary of bonded slaves details */
|
||||
|
||||
struct rte_kvargs *kvlist;
|
||||
};
|
||||
@ -168,16 +188,13 @@ slave_configure(struct rte_eth_dev *bonded_eth_dev,
|
||||
struct rte_eth_dev *slave_eth_dev);
|
||||
|
||||
void
|
||||
slave_config_clear(struct bond_dev_private *internals,
|
||||
slave_remove(struct bond_dev_private *internals,
|
||||
struct rte_eth_dev *slave_eth_dev);
|
||||
|
||||
void
|
||||
slave_config_store(struct bond_dev_private *internals,
|
||||
slave_add(struct bond_dev_private *internals,
|
||||
struct rte_eth_dev *slave_eth_dev);
|
||||
|
||||
struct slave_conf *
|
||||
slave_config_get(struct bond_dev_private *internals, uint8_t slave_port_id);
|
||||
|
||||
void
|
||||
bond_ethdev_primary_set(struct bond_dev_private *internals,
|
||||
uint8_t slave_port_id);
|
||||
@ -210,6 +227,10 @@ int
|
||||
bond_ethdev_parse_bond_mac_addr_kvarg(const char *key __rte_unused,
|
||||
const char *value, void *extra_args);
|
||||
|
||||
int
|
||||
bond_ethdev_parse_time_ms_kvarg(const char *key __rte_unused,
|
||||
const char *value, void *extra_args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user