- if VLAN is not stripped and TCI is saved: ``PKT_RX_VLAN``
- if VLAN is stripped and TCI is saved: ``PKT_RX_VLAN | PKT_RX_VLAN_STRIPPED``
+* **Modified the vlan_offload_set_t function prototype in the ethdev library.**
+
+ Changed the function prototype of ``vlan_offload_set_t``. The return value
+ has been changed from ``void`` to ``int`` so the caller to knows whether
+ the backing device supports the operation or if the operation was
+ successfully performed.
+
ABI Changes
-----------
static void avp_dev_close(struct rte_eth_dev *dev);
static void avp_dev_info_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info);
-static void avp_vlan_offload_set(struct rte_eth_dev *dev, int mask);
+static int avp_vlan_offload_set(struct rte_eth_dev *dev, int mask);
static int avp_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete);
static void avp_dev_promiscuous_enable(struct rte_eth_dev *dev);
static void avp_dev_promiscuous_disable(struct rte_eth_dev *dev);
mask = (ETH_VLAN_STRIP_MASK |
ETH_VLAN_FILTER_MASK |
ETH_VLAN_EXTEND_MASK);
- avp_vlan_offload_set(eth_dev, mask);
+ ret = avp_vlan_offload_set(eth_dev, mask);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "VLAN offload set failed by host, ret=%d\n",
+ ret);
+ goto unlock;
+ }
/* update device config */
memset(&config, 0, sizeof(config));
}
}
-static void
+static int
avp_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask)
{
struct avp_dev *avp = AVP_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
if (eth_dev->data->dev_conf.rxmode.hw_vlan_extend)
PMD_DRV_LOG(ERR, "VLAN extend offload not supported\n");
}
+
+ return 0;
}
static int
ETH_RSS_NONFRAG_IPV6_TCP | \
ETH_RSS_NONFRAG_IPV6_UDP)
-static void bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask);
+static int bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask);
/***********************/
vlan_mask |= ETH_VLAN_FILTER_MASK;
if (eth_dev->data->dev_conf.rxmode.hw_vlan_strip)
vlan_mask |= ETH_VLAN_STRIP_MASK;
- bnxt_vlan_offload_set_op(eth_dev, vlan_mask);
+ rc = bnxt_vlan_offload_set_op(eth_dev, vlan_mask);
+ if (rc)
+ goto error;
return 0;
return bnxt_del_vlan_filter(bp, vlan_id);
}
-static void
+static int
bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
{
struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
if (mask & ETH_VLAN_EXTEND_MASK)
RTE_LOG(ERR, PMD, "Extend VLAN Not supported\n");
+
+ return 0;
}
static void
return ret;
}
-static void
+static int
dpaa2_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
struct dpaa2_dev_priv *priv = dev->data->dev_private;
RTE_LOG(INFO, PMD,
"VLAN extend offload not supported\n");
}
+
+ return 0;
}
static int
return ret;
}
/* VLAN Offload Settings */
- if (priv->max_vlan_filters)
- dpaa2_vlan_offload_set(dev, ETH_VLAN_FILTER_MASK);
+ if (priv->max_vlan_filters) {
+ ret = dpaa2_vlan_offload_set(dev, ETH_VLAN_FILTER_MASK);
+ if (ret) {
+ PMD_INIT_LOG(ERR, "Error to dpaa2_vlan_offload_set:"
+ "code = %d\n", ret);
+ return ret;
+ }
+ }
+
/* if the interrupts were configured on this devices*/
if (intr_handle && (intr_handle->fd) &&
static int eth_em_vlan_filter_set(struct rte_eth_dev *dev,
uint16_t vlan_id, int on);
-static void eth_em_vlan_offload_set(struct rte_eth_dev *dev, int mask);
+static int eth_em_vlan_offload_set(struct rte_eth_dev *dev, int mask);
static void em_vlan_hw_filter_enable(struct rte_eth_dev *dev);
static void em_vlan_hw_filter_disable(struct rte_eth_dev *dev);
static void em_vlan_hw_strip_enable(struct rte_eth_dev *dev);
mask = ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK | \
ETH_VLAN_EXTEND_MASK;
- eth_em_vlan_offload_set(dev, mask);
+ ret = eth_em_vlan_offload_set(dev, mask);
+ if (ret) {
+ PMD_INIT_LOG(ERR, "Unable to update vlan offload");
+ em_dev_clear_queues(dev);
+ return ret;
+ }
/* Set Interrupt Throttling Rate to maximum allowed value. */
E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
E1000_WRITE_REG(hw, E1000_CTRL, reg);
}
-static void
+static int
eth_em_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
if(mask & ETH_VLAN_STRIP_MASK){
else
em_vlan_hw_filter_disable(dev);
}
+
+ return 0;
}
/*
static int eth_igb_vlan_tpid_set(struct rte_eth_dev *dev,
enum rte_vlan_type vlan_type,
uint16_t tpid_id);
-static void eth_igb_vlan_offload_set(struct rte_eth_dev *dev, int mask);
+static int eth_igb_vlan_offload_set(struct rte_eth_dev *dev, int mask);
static void igb_vlan_hw_filter_enable(struct rte_eth_dev *dev);
static void igb_vlan_hw_filter_disable(struct rte_eth_dev *dev);
*/
mask = ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK | \
ETH_VLAN_EXTEND_MASK;
- eth_igb_vlan_offload_set(dev, mask);
+ ret = eth_igb_vlan_offload_set(dev, mask);
+ if (ret) {
+ PMD_INIT_LOG(ERR, "Unable to set vlan offload");
+ igb_dev_clear_queues(dev);
+ return ret;
+ }
if (dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_VMDQ_ONLY) {
/* Enable VLAN filter since VMDq always use VLAN filter */
2 * VLAN_TAG_SIZE);
}
-static void
+static int
eth_igb_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
if(mask & ETH_VLAN_STRIP_MASK){
else
igb_vlan_hw_extend_disable(dev);
}
+
+ return 0;
}
return err;
}
-static void enicpmd_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask)
+static int enicpmd_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask)
{
struct enic *enic = pmd_priv(eth_dev);
dev_warning(enic,
"Configuration of extended VLAN is not supported\n");
}
+
+ return 0;
}
static int enicpmd_dev_configure(struct rte_eth_dev *eth_dev)
eth_dev->data->dev_conf.rxmode.split_hdr_size);
}
- enicpmd_vlan_offload_set(eth_dev, ETH_VLAN_STRIP_MASK);
enic->hw_ip_checksum = eth_dev->data->dev_conf.rxmode.hw_ip_checksum;
- return 0;
+ ret = enicpmd_vlan_offload_set(eth_dev, ETH_VLAN_STRIP_MASK);
+
+ return ret;
}
/* Start the device.
return 0;
}
-static void
+static int
fm10k_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
if (mask & ETH_VLAN_STRIP_MASK) {
if (!dev->data->dev_conf.rxmode.hw_vlan_filter)
PMD_INIT_LOG(ERR, "VLAN filter is always on in fm10k");
}
+
+ return 0;
}
/* Add/Remove a MAC address, and update filters to main VSI */
static int i40e_vlan_tpid_set(struct rte_eth_dev *dev,
enum rte_vlan_type vlan_type,
uint16_t tpid);
-static void i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask);
+static int i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask);
static void i40e_vlan_strip_queue_set(struct rte_eth_dev *dev,
uint16_t queue,
int on);
return ret;
}
-static void
+static int
i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
else
i40e_vsi_config_double_vlan(vsi, FALSE);
}
+
+ return 0;
}
static void
/* Apply vlan offload setting */
mask = ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK;
- i40e_vlan_offload_set(dev, mask);
+ ret = i40e_vlan_offload_set(dev, mask);
+ if (ret) {
+ PMD_DRV_LOG(INFO, "Failed to update vlan offload");
+ return ret;
+ }
/* Apply double-vlan setting, not implemented yet */
static void i40evf_dev_xstats_reset(struct rte_eth_dev *dev);
static int i40evf_vlan_filter_set(struct rte_eth_dev *dev,
uint16_t vlan_id, int on);
-static void i40evf_vlan_offload_set(struct rte_eth_dev *dev, int mask);
+static int i40evf_vlan_offload_set(struct rte_eth_dev *dev, int mask);
static void i40evf_dev_close(struct rte_eth_dev *dev);
static int i40evf_dev_reset(struct rte_eth_dev *dev);
static void i40evf_dev_promiscuous_enable(struct rte_eth_dev *dev);
i40evf_init_vlan(struct rte_eth_dev *dev)
{
/* Apply vlan offload setting */
- i40evf_vlan_offload_set(dev, ETH_VLAN_STRIP_MASK);
-
- return I40E_SUCCESS;
+ return i40evf_vlan_offload_set(dev, ETH_VLAN_STRIP_MASK);
}
-static void
+static int
i40evf_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
else
i40evf_disable_vlan_strip(dev);
}
+
+ return 0;
}
static int
uint16_t queue, bool on);
static void ixgbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue,
int on);
-static void ixgbe_vlan_offload_set(struct rte_eth_dev *dev, int mask);
+static int ixgbe_vlan_offload_set(struct rte_eth_dev *dev, int mask);
static void ixgbe_vlan_hw_strip_enable(struct rte_eth_dev *dev, uint16_t queue);
static void ixgbe_vlan_hw_strip_disable(struct rte_eth_dev *dev, uint16_t queue);
static void ixgbe_vlan_hw_extend_enable(struct rte_eth_dev *dev);
uint16_t vlan_id, int on);
static void ixgbevf_vlan_strip_queue_set(struct rte_eth_dev *dev,
uint16_t queue, int on);
-static void ixgbevf_vlan_offload_set(struct rte_eth_dev *dev, int mask);
+static int ixgbevf_vlan_offload_set(struct rte_eth_dev *dev, int mask);
static void ixgbevf_set_vfta_all(struct rte_eth_dev *dev, bool on);
static int ixgbevf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev,
uint16_t queue_id);
*/
}
-static void
+static int
ixgbe_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
if (mask & ETH_VLAN_STRIP_MASK) {
else
ixgbe_vlan_hw_extend_disable(dev);
}
+
+ return 0;
}
static void
goto error;
}
- mask = ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK |
+ mask = ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK |
ETH_VLAN_EXTEND_MASK;
- ixgbe_vlan_offload_set(dev, mask);
+ err = ixgbe_vlan_offload_set(dev, mask);
+ if (err) {
+ PMD_INIT_LOG(ERR, "Unable to set VLAN offload");
+ goto error;
+ }
if (dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_VMDQ_ONLY) {
/* Enable vlan filtering for VMDq */
/* Set HW strip */
mask = ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK |
ETH_VLAN_EXTEND_MASK;
- ixgbevf_vlan_offload_set(dev, mask);
+ err = ixgbevf_vlan_offload_set(dev, mask);
+ if (err) {
+ PMD_INIT_LOG(ERR, "Unable to set VLAN offload (%d)", err);
+ ixgbe_dev_clear_queues(dev);
+ return err;
+ }
ixgbevf_dev_rxtx_start(dev);
ixgbe_vlan_hw_strip_bitmap_set(dev, queue, on);
}
-static void
+static int
ixgbevf_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
struct ixgbe_hw *hw =
for (i = 0; i < hw->mac.max_rx_queues; i++)
ixgbevf_vlan_strip_queue_set(dev, i, on);
}
+
+ return 0;
}
int
/* mlx5_vlan.c */
int mlx5_vlan_filter_set(struct rte_eth_dev *, uint16_t, int);
-void mlx5_vlan_offload_set(struct rte_eth_dev *, int);
+int mlx5_vlan_offload_set(struct rte_eth_dev *, int);
void mlx5_vlan_strip_queue_set(struct rte_eth_dev *, uint16_t, int);
/* mlx5_trigger.c */
* @param mask
* VLAN offload bit mask.
*/
-void
+int
mlx5_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
struct priv *priv = dev->data->dev_private;
if (!priv->hw_vlan_strip) {
ERROR("VLAN stripping is not supported");
- return;
+ return 0;
}
/* Run on every RX queue and set/reset VLAN stripping. */
priv_vlan_strip_queue_set(priv, i, hw_vlan_strip);
priv_unlock(priv);
}
+
+ return 0;
}
return i;
}
-static void
+static int
nfp_net_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
uint32_t new_ctrl, update;
struct nfp_net_hw *hw;
+ int ret;
hw = NFP_NET_DEV_PRIVATE_TO_HW(dev->data->dev_private);
new_ctrl = 0;
new_ctrl = hw->ctrl & ~NFP_NET_CFG_CTRL_RXVLAN;
if (new_ctrl == 0)
- return;
+ return 0;
update = NFP_NET_CFG_UPDATE_GEN;
- if (nfp_net_reconfig(hw, new_ctrl, update) < 0)
- return;
+ ret = nfp_net_reconfig(hw, new_ctrl, update);
+ if (!ret)
+ hw->ctrl = new_ctrl;
- hw->ctrl = new_ctrl;
+ return ret;
}
/* Update Redirection Table(RETA) of Receive Side Scaling of Ethernet device */
return rc;
}
-static void qede_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask)
+static int qede_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask)
{
struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
DP_INFO(edev, "vlan offload mask %d vlan-strip %d vlan-filter %d\n",
mask, rxmode->hw_vlan_strip, rxmode->hw_vlan_filter);
+
+ return 0;
}
static void qede_prandom_bytes(uint32_t *buff)
struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
struct ecore_dev *edev = QEDE_INIT_EDEV(qdev);
struct rte_eth_rxmode *rxmode = ð_dev->data->dev_conf.rxmode;
+ int ret;
PMD_INIT_FUNC_TRACE(edev);
qdev->new_mtu = qdev->mtu;
/* Enable VLAN offloads by default */
- qede_vlan_offload_set(eth_dev, ETH_VLAN_STRIP_MASK |
+ ret = qede_vlan_offload_set(eth_dev, ETH_VLAN_STRIP_MASK |
ETH_VLAN_FILTER_MASK |
ETH_VLAN_EXTEND_MASK);
+ if (ret)
+ return ret;
DP_INFO(edev, "Device configured with RSS=%d TSS=%d\n",
QEDE_RSS_COUNT(qdev), QEDE_TSS_COUNT(qdev));
struct rte_eth_dev_info *dev_info);
static int virtio_dev_link_update(struct rte_eth_dev *dev,
int wait_to_complete);
+static int virtio_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
static void virtio_set_hwaddr(struct virtio_hw *hw);
static void virtio_get_hwaddr(struct virtio_hw *hw);
.stats_reset = virtio_dev_stats_reset,
.xstats_reset = virtio_dev_stats_reset,
.link_update = virtio_dev_link_update,
+ .vlan_offload_set = virtio_dev_vlan_offload_set,
.rx_queue_setup = virtio_dev_rx_queue_setup,
.rx_queue_intr_enable = virtio_dev_rx_queue_intr_enable,
.rx_queue_intr_disable = virtio_dev_rx_queue_intr_disable,
return (old.link_status == link.link_status) ? -1 : 0;
}
+static int
+virtio_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
+{
+ const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
+ struct virtio_hw *hw = dev->data->dev_private;
+
+ if (mask & ETH_VLAN_FILTER_MASK) {
+ if (rxmode->hw_vlan_filter &&
+ !vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VLAN)) {
+
+ PMD_DRV_LOG(NOTICE,
+ "vlan filtering not available on this host");
+
+ return -ENOTSUP;
+ }
+ }
+
+ if (mask & ETH_VLAN_STRIP_MASK)
+ hw->vlan_strip = rxmode->hw_vlan_strip;
+
+ return 0;
+}
+
static void
virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev);
static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
uint16_t vid, int on);
-static void vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
+static int vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
static void vmxnet3_mac_addr_set(struct rte_eth_dev *dev,
struct ether_addr *mac_addr);
static void vmxnet3_interrupt_handler(void *param);
devRead->rssConfDesc.confPA = hw->rss_confPA;
}
- vmxnet3_dev_vlan_offload_set(dev,
- ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK);
+ ret = vmxnet3_dev_vlan_offload_set(dev,
+ ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK);
+ if (ret)
+ return ret;
vmxnet3_write_mac(hw, dev->data->mac_addrs->addr_bytes);
return 0;
}
-static void
+static int
vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
struct vmxnet3_hw *hw = dev->data->dev_private;
VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD,
VMXNET3_CMD_UPDATE_VLAN_FILTERS);
}
+
+ return 0;
}
static void
int ret = 0;
int mask = 0;
int cur, org = 0;
+ uint64_t orig_offloads;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
+ /* save original values in case of failure */
+ orig_offloads = dev->data->dev_conf.rxmode.offloads;
+
/*check which option changed by application*/
cur = !!(offload_mask & ETH_VLAN_STRIP_OFFLOAD);
org = !!(dev->data->dev_conf.rxmode.offloads &
*/
rte_eth_convert_rx_offloads(dev->data->dev_conf.rxmode.offloads,
&dev->data->dev_conf.rxmode);
- (*dev->dev_ops->vlan_offload_set)(dev, mask);
+ ret = (*dev->dev_ops->vlan_offload_set)(dev, mask);
+ if (ret) {
+ /* hit an error restore original values */
+ dev->data->dev_conf.rxmode.offloads = orig_offloads;
+ rte_eth_convert_rx_offloads(dev->data->dev_conf.rxmode.offloads,
+ &dev->data->dev_conf.rxmode);
+ }
return ret;
}
enum rte_vlan_type type, uint16_t tpid);
/**< @internal set the outer/inner VLAN-TPID by an Ethernet device. */
-typedef void (*vlan_offload_set_t)(struct rte_eth_dev *dev, int mask);
+typedef int (*vlan_offload_set_t)(struct rte_eth_dev *dev, int mask);
/**< @internal set VLAN offload function by an Ethernet device. */
typedef int (*vlan_pvid_set_t)(struct rte_eth_dev *dev,