@@ -459,3 +459,58 @@ show bypass config
Show the bypass configuration for a bypass enabled NIC using the lowest port on the NIC::
testpmd> show bypass config (port_id)
+
+
+Secondary Process Support
+-------------------------
+
+IXGBE Physical Function Driver
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following ethdev API's are currently not supported for use in secondary processes:
+
+* ``rte_eth_dev_start``
+* ``rte_eth_dev_stop``
+* ``rte_eth_dev_set_link_up``
+* ``rte_eth_dev_set_link_down``
+* ``rte_eth_dev_rx_intr_enable``
+* ``rte_eth_dev_rx_intr_disable``
+* ``rte_eth_link_get``
+* ``rte_eth_dev_fw_version_get``
+* ``rte_eth_dev_rx_intr_enable``
+* ``rte_eth_dev_rx_intr_disable``
+* ``rte_eth_dev_led_on``
+* ``rte_eth_dev_led_off``
+* ``rte_eth_dev_flow_ctrl_set``
+* ``rte_eth_dev_priority_flow_ctrl_set``
+* ``rte_eth_dev_default_mac_addr_set``
+* ``rte_eth_dev_mac_addr_add``
+* ``rte_eth_dev_mac_addr_remove``
+* ``rte_eth_dev_set_mc_addr_list``
+* ``rte_eth_dev_get_eeprom``
+* ``rte_eth_dev_set_eeprom``
+* ``rte_eth_dev_get_module_info``
+* ``rte_eth_dev_get_module_eeprom``
+
+IXGBE Virtual Function Driver
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following ethdev API's are currently not supported for use in secondary processes:
+
+* ``rte_eth_dev_start``
+* ``rte_eth_dev_stop``
+* ``rte_eth_promiscuous_enable``
+* ``rte_eth_promiscuous_disable``
+* ``rte_eth_allmulticast_enable``
+* ``rte_eth_allmulticast_disable``
+* ``rte_eth_dev_set_mtu``
+* ``rte_eth_dev_set_link_up``
+* ``rte_eth_dev_set_link_down``
+* ``rte_eth_link_get``
+* ``rte_eth_dev_default_mac_addr_set``
+* ``rte_eth_dev_mac_addr_add``
+* ``rte_eth_dev_mac_addr_remove``
+* ``rte_eth_dev_set_mc_addr_list``
+* ``rte_eth_dev_vlan_filter``
+* ``rte_eth_dev_rx_intr_enable``
+* ``rte_eth_dev_rx_intr_disable``
@@ -2630,6 +2630,14 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
struct ixgbe_macsec_setting *macsec_setting =
IXGBE_DEV_PRIVATE_TO_MACSEC_SETTING(dev->data->dev_private);
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
PMD_INIT_FUNC_TRACE();
/* Stop the link setup handler before resetting the HW. */
@@ -2918,6 +2926,14 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
PMD_INIT_FUNC_TRACE();
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
ixgbe_dev_wait_setup_link_complete(dev, 0);
/* disable interrupts */
@@ -2980,6 +2996,15 @@ ixgbe_dev_set_link_up(struct rte_eth_dev *dev)
{
struct ixgbe_hw *hw =
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
if (hw->mac.type == ixgbe_mac_82599EB) {
#ifdef RTE_LIBRTE_IXGBE_BYPASS
if (hw->device_id == IXGBE_DEV_ID_82599_BYPASS) {
@@ -3011,6 +3036,15 @@ ixgbe_dev_set_link_down(struct rte_eth_dev *dev)
{
struct ixgbe_hw *hw =
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
if (hw->mac.type == ixgbe_mac_82599EB) {
#ifdef RTE_LIBRTE_IXGBE_BYPASS
if (hw->device_id == IXGBE_DEV_ID_82599_BYPASS) {
@@ -3874,6 +3908,14 @@ ixgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
struct ixgbe_nvm_version nvm_ver;
int ret;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
ixgbe_get_oem_prod_version(hw, &nvm_ver);
if (nvm_ver.oem_valid) {
snprintf(fw_version, fw_size, "%x.%x.%x",
@@ -4784,6 +4826,14 @@ ixgbe_dev_led_on(struct rte_eth_dev *dev)
{
struct ixgbe_hw *hw;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
return ixgbe_led_on(hw, 0) == IXGBE_SUCCESS ? 0 : -ENOTSUP;
}
@@ -4793,6 +4843,14 @@ ixgbe_dev_led_off(struct rte_eth_dev *dev)
{
struct ixgbe_hw *hw;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
return ixgbe_led_off(hw, 0) == IXGBE_SUCCESS ? 0 : -ENOTSUP;
}
@@ -4866,6 +4924,14 @@ ixgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
ixgbe_fc_full
};
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
PMD_INIT_FUNC_TRACE();
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -5071,6 +5137,14 @@ ixgbe_priority_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *p
ixgbe_fc_full
};
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
PMD_INIT_FUNC_TRACE();
ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_RX_CONFIG, map);
@@ -5219,6 +5293,14 @@ ixgbe_add_rar(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint32_t enable_addr = 1;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
return ixgbe_set_rar(hw, index, mac_addr->addr_bytes,
pool, enable_addr);
}
@@ -5228,6 +5310,14 @@ ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index)
{
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return;
+
ixgbe_clear_rar(hw, index);
}
@@ -5236,6 +5326,14 @@ ixgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *addr)
{
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
ixgbe_remove_rar(dev, 0);
ixgbe_add_rar(dev, addr, 0, pci_dev->max_vfs);
@@ -5395,6 +5493,14 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)
int err, mask = 0;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
PMD_INIT_FUNC_TRACE();
/* Stop the link setup handler before resetting the HW. */
@@ -5498,6 +5604,14 @@ ixgbevf_dev_stop(struct rte_eth_dev *dev)
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
if (hw->adapter_stopped)
return 0;
@@ -5613,6 +5727,14 @@ ixgbevf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
uint32_t vid_bit = 0;
int ret = 0;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
PMD_INIT_FUNC_TRACE();
/* vind is not used in VF driver, set to 0, check ixgbe_set_vfta_vf */
@@ -5841,6 +5963,10 @@ ixgbevf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint32_t vec = IXGBE_MISC_VEC_ID;
+ /* device interrupts are only subscribed to in primary processes */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
if (rte_intr_allow_others(intr_handle))
vec = IXGBE_RX_VEC_START;
intr->mask |= (1 << vec);
@@ -5863,6 +5989,10 @@ ixgbevf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
uint32_t vec = IXGBE_MISC_VEC_ID;
+ /* device interrupts are only subscribed to in primary processes */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
if (rte_intr_allow_others(intr_handle))
vec = IXGBE_RX_VEC_START;
intr->mask &= ~(1 << vec);
@@ -5883,6 +6013,10 @@ ixgbe_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
struct ixgbe_interrupt *intr =
IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
+ /* device interrupts are only subscribed to in primary processes */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
if (queue_id < 16) {
ixgbe_disable_intr(hw);
intr->mask |= (1 << queue_id);
@@ -5910,6 +6044,10 @@ ixgbe_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
struct ixgbe_interrupt *intr =
IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
+ /* device interrupts are only subscribed to in primary processes */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
if (queue_id < 16) {
ixgbe_disable_intr(hw);
intr->mask &= ~(1 << queue_id);
@@ -6189,6 +6327,14 @@ ixgbevf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
int diag;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
/*
* On a 82599 VF, adding again the same MAC addr is not an idempotent
* operation. Trap this case to avoid exhausting the [very limited]
@@ -6215,6 +6361,14 @@ ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index)
uint32_t i;
int diag;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return;
+
/*
* The IXGBE_VF_SET_MACVLAN command of the ixgbe-pf driver does
* not support the deletion of a given MAC address.
@@ -6255,6 +6409,14 @@ ixgbevf_set_default_mac_addr(struct rte_eth_dev *dev,
{
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
hw->mac.ops.set_rar(hw, 0, (void *)addr, 0, 0);
return 0;
@@ -6441,6 +6603,14 @@ ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
uint32_t max_frame = mtu + IXGBE_ETH_OVERHEAD;
struct rte_eth_dev_data *dev_data = dev->data;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
if (mtu < RTE_ETHER_MIN_MTU || max_frame > RTE_ETHER_MAX_JUMBO_FRAME_LEN)
@@ -6732,6 +6902,14 @@ ixgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
struct ixgbe_hw *hw;
u8 *mc_addr_list;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
mc_addr_list = (u8 *)mc_addr_set;
return ixgbe_update_mc_addr_list(hw, mc_addr_list, nb_mc_addr,
@@ -7152,6 +7330,14 @@ ixgbe_get_eeprom(struct rte_eth_dev *dev,
uint16_t *data = in_eeprom->data;
int first, length;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
first = in_eeprom->offset >> 1;
length = in_eeprom->length >> 1;
if ((first > hw->eeprom.word_size) ||
@@ -7172,6 +7358,14 @@ ixgbe_set_eeprom(struct rte_eth_dev *dev,
uint16_t *data = in_eeprom->data;
int first, length;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
first = in_eeprom->offset >> 1;
length = in_eeprom->length >> 1;
if ((first > hw->eeprom.word_size) ||
@@ -7192,6 +7386,14 @@ ixgbe_get_module_info(struct rte_eth_dev *dev,
uint8_t sff8472_rev, addr_mode;
bool page_swap = false;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
/* Check whether we support SFF-8472 or not */
status = hw->phy.ops.read_i2c_eeprom(hw,
IXGBE_SFF_SFF_8472_COMP,
@@ -7237,6 +7439,14 @@ ixgbe_get_module_eeprom(struct rte_eth_dev *dev,
uint8_t *data = info->data;
uint32_t i = 0;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
for (i = info->offset; i < info->offset + info->length; i++) {
if (i < RTE_ETH_MODULE_SFF_8079_LEN)
status = hw->phy.ops.read_i2c_eeprom(hw, i, &databyte);
@@ -7832,6 +8042,14 @@ ixgbevf_dev_promiscuous_enable(struct rte_eth_dev *dev)
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
int ret;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
switch (hw->mac.ops.update_xcast_mode(hw, IXGBEVF_XCAST_MODE_PROMISC)) {
case IXGBE_SUCCESS:
ret = 0;
@@ -7854,6 +8072,14 @@ ixgbevf_dev_promiscuous_disable(struct rte_eth_dev *dev)
int mode = IXGBEVF_XCAST_MODE_NONE;
int ret;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
if (dev->data->all_multicast)
mode = IXGBEVF_XCAST_MODE_ALLMULTI;
@@ -7879,6 +8105,14 @@ ixgbevf_dev_allmulticast_enable(struct rte_eth_dev *dev)
int ret;
int mode = IXGBEVF_XCAST_MODE_ALLMULTI;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
if (dev->data->promiscuous)
return 0;
@@ -7903,6 +8137,14 @@ ixgbevf_dev_allmulticast_disable(struct rte_eth_dev *dev)
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
int ret;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
if (dev->data->promiscuous)
return 0;