net/ixgbe: fix single VLAN tag to be outer VLAN tag
Previously, a single VLAN header is treated as inner VLAN,
but generally, a single VLAN header is treated as the outer
VLAN header.
The patch fixes the ether type of a single VLAN type, and
enables configuring inner and outer TPID for double VLAN.
Fixes: 19b16e2f64
("ethdev: add vlan type when setting ether type")
Signed-off-by: Beilei Xing <beilei.xing@intel.com>
This commit is contained in:
parent
5b2d37858d
commit
2b84092427
@ -158,6 +158,9 @@ enum ixgbevf_xcast_modes {
|
||||
IXGBEVF_XCAST_MODE_ALLMULTI,
|
||||
};
|
||||
|
||||
#define IXGBE_EXVET_VET_EXT_SHIFT 16
|
||||
#define IXGBE_DMATXCTL_VT_MASK 0xFFFF0000
|
||||
|
||||
static int eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev);
|
||||
static int eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev);
|
||||
static int ixgbe_dev_configure(struct rte_eth_dev *dev);
|
||||
@ -1599,15 +1602,47 @@ ixgbe_vlan_tpid_set(struct rte_eth_dev *dev,
|
||||
struct ixgbe_hw *hw =
|
||||
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
|
||||
int ret = 0;
|
||||
uint32_t reg;
|
||||
uint32_t qinq;
|
||||
|
||||
qinq = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
|
||||
qinq &= IXGBE_DMATXCTL_GDV;
|
||||
|
||||
switch (vlan_type) {
|
||||
case ETH_VLAN_TYPE_INNER:
|
||||
/* Only the high 16-bits is valid */
|
||||
IXGBE_WRITE_REG(hw, IXGBE_EXVET, tpid << 16);
|
||||
if (qinq) {
|
||||
reg = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
|
||||
reg = (reg & (~IXGBE_VLNCTRL_VET)) | (uint32_t)tpid;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, reg);
|
||||
reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
|
||||
reg = (reg & (~IXGBE_DMATXCTL_VT_MASK))
|
||||
| ((uint32_t)tpid << IXGBE_DMATXCTL_VT_SHIFT);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
|
||||
} else {
|
||||
ret = -ENOTSUP;
|
||||
PMD_DRV_LOG(ERR, "Inner type is not supported"
|
||||
" by single VLAN");
|
||||
}
|
||||
break;
|
||||
case ETH_VLAN_TYPE_OUTER:
|
||||
if (qinq) {
|
||||
/* Only the high 16-bits is valid */
|
||||
IXGBE_WRITE_REG(hw, IXGBE_EXVET, (uint32_t)tpid <<
|
||||
IXGBE_EXVET_VET_EXT_SHIFT);
|
||||
} else {
|
||||
reg = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
|
||||
reg = (reg & (~IXGBE_VLNCTRL_VET)) | (uint32_t)tpid;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, reg);
|
||||
reg = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
|
||||
reg = (reg & (~IXGBE_DMATXCTL_VT_MASK))
|
||||
| ((uint32_t)tpid << IXGBE_DMATXCTL_VT_SHIFT);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
PMD_DRV_LOG(ERR, "Unsupported vlan type %d\n", vlan_type);
|
||||
PMD_DRV_LOG(ERR, "Unsupported VLAN type %d", vlan_type);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1157,7 +1157,7 @@ typedef int (*vlan_filter_set_t)(struct rte_eth_dev *dev,
|
||||
|
||||
typedef int (*vlan_tpid_set_t)(struct rte_eth_dev *dev,
|
||||
enum rte_vlan_type type, uint16_t tpid);
|
||||
/**< @internal set the outer VLAN-TPID by an Ethernet device. */
|
||||
/**< @internal set the outer/inner VLAN-TPID by an Ethernet device. */
|
||||
|
||||
typedef void (*vlan_offload_set_t)(struct rte_eth_dev *dev, int mask);
|
||||
/**< @internal set VLAN offload function by an Ethernet device. */
|
||||
@ -1443,7 +1443,7 @@ struct eth_dev_ops {
|
||||
/**< Get packet types supported and identified by device*/
|
||||
mtu_set_t mtu_set; /**< Set MTU. */
|
||||
vlan_filter_set_t vlan_filter_set; /**< Filter VLAN Setup. */
|
||||
vlan_tpid_set_t vlan_tpid_set; /**< Outer VLAN TPID Setup. */
|
||||
vlan_tpid_set_t vlan_tpid_set; /**< Outer/Inner VLAN TPID Setup. */
|
||||
vlan_strip_queue_set_t vlan_strip_queue_set; /**< VLAN Stripping on queue. */
|
||||
vlan_offload_set_t vlan_offload_set; /**< Set VLAN Offload. */
|
||||
vlan_pvid_set_t vlan_pvid_set; /**< Set port based TX VLAN insertion */
|
||||
|
Loading…
Reference in New Issue
Block a user