net/igc: support VLAN
Below ops ware added: vlan_filter_set vlan_offload_set vlan_tpid_set vlan_strip_queue_set Signed-off-by: Alvin Zhang <alvinx.zhang@intel.com> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
This commit is contained in:
parent
bd3fcf0d0f
commit
5f266d0d8c
@ -30,6 +30,8 @@ Rx interrupt = Y
|
|||||||
Flow control = Y
|
Flow control = Y
|
||||||
RSS key update = Y
|
RSS key update = Y
|
||||||
RSS reta update = Y
|
RSS reta update = Y
|
||||||
|
VLAN filter = Y
|
||||||
|
VLAN offload = Y
|
||||||
Linux UIO = Y
|
Linux UIO = Y
|
||||||
Linux VFIO = Y
|
Linux VFIO = Y
|
||||||
x86-64 = Y
|
x86-64 = Y
|
||||||
|
@ -40,3 +40,38 @@ Foxville LM (I225 LM): Client 2.5G LAN vPro Corporate
|
|||||||
Foxville V (I225 V): Client 2.5G LAN Consumer
|
Foxville V (I225 V): Client 2.5G LAN Consumer
|
||||||
Foxville I (I225 I): Client 2.5G Industrial Temp
|
Foxville I (I225 I): Client 2.5G Industrial Temp
|
||||||
Foxville V (I225 K): Client 2.5G LAN Consumer
|
Foxville V (I225 K): Client 2.5G LAN Consumer
|
||||||
|
|
||||||
|
|
||||||
|
Sample Application Notes
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
Vlan filter
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
VLAN stripping off only works with inner vlan.
|
||||||
|
Only the outer VLAN TPID can be set to a vlan other than 0x8100.
|
||||||
|
|
||||||
|
If extend VLAN is enabled:
|
||||||
|
|
||||||
|
- The VLAN header in a packet that carries a single VLAN header is treated as the external VLAN.
|
||||||
|
|
||||||
|
- Foxville expects that any transmitted packet to have at least the external VLAN added by the
|
||||||
|
software. For those packets where an external VLAN is not present, any offload that relates to
|
||||||
|
inner fields to the EtherType might not be provided.
|
||||||
|
|
||||||
|
- If VLAN TX-OFFLOAD is enabled and the packet does not contain an external VLAN, the packet is
|
||||||
|
dropped, and if configured, the queue from which the packet was sent is disabled.
|
||||||
|
|
||||||
|
To start ``testpmd``, add vlan 10 to port, set vlan stripping off on, set extend on, set TPID of
|
||||||
|
outer VLAN to 0x9100:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
./app/testpmd -l 4-8 -- -i
|
||||||
|
...
|
||||||
|
|
||||||
|
testpmd> vlan set filter on 0
|
||||||
|
testpmd> rx_vlan add 10 0
|
||||||
|
testpmd> vlan set strip off 0
|
||||||
|
testpmd> vlan set extend on 0
|
||||||
|
testpmd> vlan set outer tpid 0x9100 0
|
||||||
|
@ -50,6 +50,10 @@
|
|||||||
/* External VLAN Enable bit mask */
|
/* External VLAN Enable bit mask */
|
||||||
#define IGC_CTRL_EXT_EXT_VLAN (1u << 26)
|
#define IGC_CTRL_EXT_EXT_VLAN (1u << 26)
|
||||||
|
|
||||||
|
/* External VLAN Ether Type bit mask and shift */
|
||||||
|
#define IGC_VET_EXT 0xFFFF0000
|
||||||
|
#define IGC_VET_EXT_SHIFT 16
|
||||||
|
|
||||||
/* Per Queue Good Packets Received Count */
|
/* Per Queue Good Packets Received Count */
|
||||||
#define IGC_PQGPRC(idx) (0x10010 + 0x100 * (idx))
|
#define IGC_PQGPRC(idx) (0x10010 + 0x100 * (idx))
|
||||||
/* Per Queue Good Octets Received Count */
|
/* Per Queue Good Octets Received Count */
|
||||||
@ -227,6 +231,11 @@ static int eth_igc_rss_hash_update(struct rte_eth_dev *dev,
|
|||||||
struct rte_eth_rss_conf *rss_conf);
|
struct rte_eth_rss_conf *rss_conf);
|
||||||
static int eth_igc_rss_hash_conf_get(struct rte_eth_dev *dev,
|
static int eth_igc_rss_hash_conf_get(struct rte_eth_dev *dev,
|
||||||
struct rte_eth_rss_conf *rss_conf);
|
struct rte_eth_rss_conf *rss_conf);
|
||||||
|
static int
|
||||||
|
eth_igc_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on);
|
||||||
|
static int eth_igc_vlan_offload_set(struct rte_eth_dev *dev, int mask);
|
||||||
|
static int eth_igc_vlan_tpid_set(struct rte_eth_dev *dev,
|
||||||
|
enum rte_vlan_type vlan_type, uint16_t tpid);
|
||||||
|
|
||||||
static const struct eth_dev_ops eth_igc_ops = {
|
static const struct eth_dev_ops eth_igc_ops = {
|
||||||
.dev_configure = eth_igc_configure,
|
.dev_configure = eth_igc_configure,
|
||||||
@ -279,6 +288,10 @@ static const struct eth_dev_ops eth_igc_ops = {
|
|||||||
.reta_query = eth_igc_rss_reta_query,
|
.reta_query = eth_igc_rss_reta_query,
|
||||||
.rss_hash_update = eth_igc_rss_hash_update,
|
.rss_hash_update = eth_igc_rss_hash_update,
|
||||||
.rss_hash_conf_get = eth_igc_rss_hash_conf_get,
|
.rss_hash_conf_get = eth_igc_rss_hash_conf_get,
|
||||||
|
.vlan_filter_set = eth_igc_vlan_filter_set,
|
||||||
|
.vlan_offload_set = eth_igc_vlan_offload_set,
|
||||||
|
.vlan_tpid_set = eth_igc_vlan_tpid_set,
|
||||||
|
.vlan_strip_queue_set = eth_igc_vlan_strip_queue_set,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -950,6 +963,11 @@ eth_igc_start(struct rte_eth_dev *dev)
|
|||||||
|
|
||||||
igc_clear_hw_cntrs_base_generic(hw);
|
igc_clear_hw_cntrs_base_generic(hw);
|
||||||
|
|
||||||
|
/* VLAN Offload Settings */
|
||||||
|
eth_igc_vlan_offload_set(dev,
|
||||||
|
ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK |
|
||||||
|
ETH_VLAN_EXTEND_MASK);
|
||||||
|
|
||||||
/* Setup link speed and duplex */
|
/* Setup link speed and duplex */
|
||||||
speeds = &dev->data->dev_conf.link_speeds;
|
speeds = &dev->data->dev_conf.link_speeds;
|
||||||
if (*speeds == ETH_LINK_SPEED_AUTONEG) {
|
if (*speeds == ETH_LINK_SPEED_AUTONEG) {
|
||||||
@ -1443,6 +1461,7 @@ eth_igc_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
|
|||||||
dev_info->max_mac_addrs = hw->mac.rar_entry_count;
|
dev_info->max_mac_addrs = hw->mac.rar_entry_count;
|
||||||
dev_info->rx_offload_capa = IGC_RX_OFFLOAD_ALL;
|
dev_info->rx_offload_capa = IGC_RX_OFFLOAD_ALL;
|
||||||
dev_info->tx_offload_capa = IGC_TX_OFFLOAD_ALL;
|
dev_info->tx_offload_capa = IGC_TX_OFFLOAD_ALL;
|
||||||
|
dev_info->rx_queue_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP;
|
||||||
|
|
||||||
dev_info->max_rx_queues = IGC_QUEUE_PAIRS_NUM;
|
dev_info->max_rx_queues = IGC_QUEUE_PAIRS_NUM;
|
||||||
dev_info->max_tx_queues = IGC_QUEUE_PAIRS_NUM;
|
dev_info->max_tx_queues = IGC_QUEUE_PAIRS_NUM;
|
||||||
@ -2358,6 +2377,192 @@ eth_igc_rss_hash_conf_get(struct rte_eth_dev *dev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
eth_igc_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
|
||||||
|
{
|
||||||
|
struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
|
||||||
|
struct igc_vfta *shadow_vfta = IGC_DEV_PRIVATE_VFTA(dev);
|
||||||
|
uint32_t vfta;
|
||||||
|
uint32_t vid_idx;
|
||||||
|
uint32_t vid_bit;
|
||||||
|
|
||||||
|
vid_idx = (vlan_id >> IGC_VFTA_ENTRY_SHIFT) & IGC_VFTA_ENTRY_MASK;
|
||||||
|
vid_bit = 1u << (vlan_id & IGC_VFTA_ENTRY_BIT_SHIFT_MASK);
|
||||||
|
vfta = shadow_vfta->vfta[vid_idx];
|
||||||
|
if (on)
|
||||||
|
vfta |= vid_bit;
|
||||||
|
else
|
||||||
|
vfta &= ~vid_bit;
|
||||||
|
IGC_WRITE_REG_ARRAY(hw, IGC_VFTA, vid_idx, vfta);
|
||||||
|
|
||||||
|
/* update local VFTA copy */
|
||||||
|
shadow_vfta->vfta[vid_idx] = vfta;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
igc_vlan_hw_filter_disable(struct rte_eth_dev *dev)
|
||||||
|
{
|
||||||
|
struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
|
||||||
|
igc_read_reg_check_clear_bits(hw, IGC_RCTL,
|
||||||
|
IGC_RCTL_CFIEN | IGC_RCTL_VFE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
igc_vlan_hw_filter_enable(struct rte_eth_dev *dev)
|
||||||
|
{
|
||||||
|
struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
|
||||||
|
struct igc_vfta *shadow_vfta = IGC_DEV_PRIVATE_VFTA(dev);
|
||||||
|
uint32_t reg_val;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Filter Table Enable, CFI not used for packet acceptance */
|
||||||
|
reg_val = IGC_READ_REG(hw, IGC_RCTL);
|
||||||
|
reg_val &= ~IGC_RCTL_CFIEN;
|
||||||
|
reg_val |= IGC_RCTL_VFE;
|
||||||
|
IGC_WRITE_REG(hw, IGC_RCTL, reg_val);
|
||||||
|
|
||||||
|
/* restore VFTA table */
|
||||||
|
for (i = 0; i < IGC_VFTA_SIZE; i++)
|
||||||
|
IGC_WRITE_REG_ARRAY(hw, IGC_VFTA, i, shadow_vfta->vfta[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
igc_vlan_hw_strip_disable(struct rte_eth_dev *dev)
|
||||||
|
{
|
||||||
|
struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
|
||||||
|
|
||||||
|
igc_read_reg_check_clear_bits(hw, IGC_CTRL, IGC_CTRL_VME);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
igc_vlan_hw_strip_enable(struct rte_eth_dev *dev)
|
||||||
|
{
|
||||||
|
struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
|
||||||
|
|
||||||
|
igc_read_reg_check_set_bits(hw, IGC_CTRL, IGC_CTRL_VME);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
igc_vlan_hw_extend_disable(struct rte_eth_dev *dev)
|
||||||
|
{
|
||||||
|
struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
|
||||||
|
uint32_t ctrl_ext;
|
||||||
|
|
||||||
|
ctrl_ext = IGC_READ_REG(hw, IGC_CTRL_EXT);
|
||||||
|
|
||||||
|
/* if extend vlan hasn't been enabled */
|
||||||
|
if ((ctrl_ext & IGC_CTRL_EXT_EXT_VLAN) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((dev->data->dev_conf.rxmode.offloads &
|
||||||
|
DEV_RX_OFFLOAD_JUMBO_FRAME) == 0)
|
||||||
|
goto write_ext_vlan;
|
||||||
|
|
||||||
|
/* Update maximum packet length */
|
||||||
|
if (dev->data->dev_conf.rxmode.max_rx_pkt_len <
|
||||||
|
RTE_ETHER_MIN_MTU + VLAN_TAG_SIZE) {
|
||||||
|
PMD_DRV_LOG(ERR, "Maximum packet length %u error, min is %u",
|
||||||
|
dev->data->dev_conf.rxmode.max_rx_pkt_len,
|
||||||
|
VLAN_TAG_SIZE + RTE_ETHER_MIN_MTU);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
dev->data->dev_conf.rxmode.max_rx_pkt_len -= VLAN_TAG_SIZE;
|
||||||
|
IGC_WRITE_REG(hw, IGC_RLPML,
|
||||||
|
dev->data->dev_conf.rxmode.max_rx_pkt_len);
|
||||||
|
|
||||||
|
write_ext_vlan:
|
||||||
|
IGC_WRITE_REG(hw, IGC_CTRL_EXT, ctrl_ext & ~IGC_CTRL_EXT_EXT_VLAN);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
igc_vlan_hw_extend_enable(struct rte_eth_dev *dev)
|
||||||
|
{
|
||||||
|
struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
|
||||||
|
uint32_t ctrl_ext;
|
||||||
|
|
||||||
|
ctrl_ext = IGC_READ_REG(hw, IGC_CTRL_EXT);
|
||||||
|
|
||||||
|
/* if extend vlan has been enabled */
|
||||||
|
if (ctrl_ext & IGC_CTRL_EXT_EXT_VLAN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((dev->data->dev_conf.rxmode.offloads &
|
||||||
|
DEV_RX_OFFLOAD_JUMBO_FRAME) == 0)
|
||||||
|
goto write_ext_vlan;
|
||||||
|
|
||||||
|
/* Update maximum packet length */
|
||||||
|
if (dev->data->dev_conf.rxmode.max_rx_pkt_len >
|
||||||
|
MAX_RX_JUMBO_FRAME_SIZE - VLAN_TAG_SIZE) {
|
||||||
|
PMD_DRV_LOG(ERR, "Maximum packet length %u error, max is %u",
|
||||||
|
dev->data->dev_conf.rxmode.max_rx_pkt_len +
|
||||||
|
VLAN_TAG_SIZE, MAX_RX_JUMBO_FRAME_SIZE);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
dev->data->dev_conf.rxmode.max_rx_pkt_len += VLAN_TAG_SIZE;
|
||||||
|
IGC_WRITE_REG(hw, IGC_RLPML,
|
||||||
|
dev->data->dev_conf.rxmode.max_rx_pkt_len);
|
||||||
|
|
||||||
|
write_ext_vlan:
|
||||||
|
IGC_WRITE_REG(hw, IGC_CTRL_EXT, ctrl_ext | IGC_CTRL_EXT_EXT_VLAN);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
eth_igc_vlan_offload_set(struct rte_eth_dev *dev, int mask)
|
||||||
|
{
|
||||||
|
struct rte_eth_rxmode *rxmode;
|
||||||
|
|
||||||
|
rxmode = &dev->data->dev_conf.rxmode;
|
||||||
|
if (mask & ETH_VLAN_STRIP_MASK) {
|
||||||
|
if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
|
||||||
|
igc_vlan_hw_strip_enable(dev);
|
||||||
|
else
|
||||||
|
igc_vlan_hw_strip_disable(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask & ETH_VLAN_FILTER_MASK) {
|
||||||
|
if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER)
|
||||||
|
igc_vlan_hw_filter_enable(dev);
|
||||||
|
else
|
||||||
|
igc_vlan_hw_filter_disable(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask & ETH_VLAN_EXTEND_MASK) {
|
||||||
|
if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_EXTEND)
|
||||||
|
return igc_vlan_hw_extend_enable(dev);
|
||||||
|
else
|
||||||
|
return igc_vlan_hw_extend_disable(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
eth_igc_vlan_tpid_set(struct rte_eth_dev *dev,
|
||||||
|
enum rte_vlan_type vlan_type,
|
||||||
|
uint16_t tpid)
|
||||||
|
{
|
||||||
|
struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
|
||||||
|
uint32_t reg_val;
|
||||||
|
|
||||||
|
/* only outer TPID of double VLAN can be configured*/
|
||||||
|
if (vlan_type == ETH_VLAN_TYPE_OUTER) {
|
||||||
|
reg_val = IGC_READ_REG(hw, IGC_VET);
|
||||||
|
reg_val = (reg_val & (~IGC_VET_EXT)) |
|
||||||
|
((uint32_t)tpid << IGC_VET_EXT_SHIFT);
|
||||||
|
IGC_WRITE_REG(hw, IGC_VET, reg_val);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* all other TPID values are read-only*/
|
||||||
|
PMD_DRV_LOG(ERR, "Not supported");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
eth_igc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
|
eth_igc_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
|
||||||
struct rte_pci_device *pci_dev)
|
struct rte_pci_device *pci_dev)
|
||||||
|
@ -17,6 +17,10 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define IGC_RSS_RDT_SIZD 128
|
#define IGC_RSS_RDT_SIZD 128
|
||||||
|
|
||||||
|
/* VLAN filter table size */
|
||||||
|
#define IGC_VFTA_SIZE 128
|
||||||
|
|
||||||
#define IGC_QUEUE_PAIRS_NUM 4
|
#define IGC_QUEUE_PAIRS_NUM 4
|
||||||
|
|
||||||
#define IGC_HKEY_MAX_INDEX 10
|
#define IGC_HKEY_MAX_INDEX 10
|
||||||
@ -54,6 +58,9 @@ extern "C" {
|
|||||||
#define IGC_TX_MAX_MTU_SEG UINT8_MAX
|
#define IGC_TX_MAX_MTU_SEG UINT8_MAX
|
||||||
|
|
||||||
#define IGC_RX_OFFLOAD_ALL ( \
|
#define IGC_RX_OFFLOAD_ALL ( \
|
||||||
|
DEV_RX_OFFLOAD_VLAN_STRIP | \
|
||||||
|
DEV_RX_OFFLOAD_VLAN_FILTER | \
|
||||||
|
DEV_RX_OFFLOAD_VLAN_EXTEND | \
|
||||||
DEV_RX_OFFLOAD_IPV4_CKSUM | \
|
DEV_RX_OFFLOAD_IPV4_CKSUM | \
|
||||||
DEV_RX_OFFLOAD_UDP_CKSUM | \
|
DEV_RX_OFFLOAD_UDP_CKSUM | \
|
||||||
DEV_RX_OFFLOAD_TCP_CKSUM | \
|
DEV_RX_OFFLOAD_TCP_CKSUM | \
|
||||||
@ -113,6 +120,11 @@ struct igc_hw_queue_stats {
|
|||||||
/* per transmit queue drop packet count */
|
/* per transmit queue drop packet count */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* local vfta copy */
|
||||||
|
struct igc_vfta {
|
||||||
|
uint32_t vfta[IGC_VFTA_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structure to store private data for each driver instance (for each port).
|
* Structure to store private data for each driver instance (for each port).
|
||||||
*/
|
*/
|
||||||
@ -124,6 +136,7 @@ struct igc_adapter {
|
|||||||
int16_t rxq_stats_map[IGC_QUEUE_PAIRS_NUM];
|
int16_t rxq_stats_map[IGC_QUEUE_PAIRS_NUM];
|
||||||
|
|
||||||
struct igc_interrupt intr;
|
struct igc_interrupt intr;
|
||||||
|
struct igc_vfta shadow_vfta;
|
||||||
bool stopped;
|
bool stopped;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -141,6 +154,9 @@ struct igc_adapter {
|
|||||||
#define IGC_DEV_PRIVATE_INTR(_dev) \
|
#define IGC_DEV_PRIVATE_INTR(_dev) \
|
||||||
(&((struct igc_adapter *)(_dev)->data->dev_private)->intr)
|
(&((struct igc_adapter *)(_dev)->data->dev_private)->intr)
|
||||||
|
|
||||||
|
#define IGC_DEV_PRIVATE_VFTA(_dev) \
|
||||||
|
(&((struct igc_adapter *)(_dev)->data->dev_private)->shadow_vfta)
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
igc_read_reg_check_set_bits(struct igc_hw *hw, uint32_t reg, uint32_t bits)
|
igc_read_reg_check_set_bits(struct igc_hw *hw, uint32_t reg, uint32_t bits)
|
||||||
{
|
{
|
||||||
|
@ -1162,6 +1162,16 @@ igc_rx_init(struct rte_eth_dev *dev)
|
|||||||
IGC_WRITE_REG(hw, IGC_RDH(rxq->reg_idx), 0);
|
IGC_WRITE_REG(hw, IGC_RDH(rxq->reg_idx), 0);
|
||||||
IGC_WRITE_REG(hw, IGC_RDT(rxq->reg_idx),
|
IGC_WRITE_REG(hw, IGC_RDT(rxq->reg_idx),
|
||||||
rxq->nb_rx_desc - 1);
|
rxq->nb_rx_desc - 1);
|
||||||
|
|
||||||
|
/* strip queue vlan offload */
|
||||||
|
if (rxq->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) {
|
||||||
|
uint32_t dvmolr;
|
||||||
|
dvmolr = IGC_READ_REG(hw, IGC_DVMOLR(rxq->queue_id));
|
||||||
|
|
||||||
|
/* If vlan been stripped off, the CRC is meaningless. */
|
||||||
|
dvmolr |= IGC_DVMOLR_STRVLAN | IGC_DVMOLR_STRCRC;
|
||||||
|
IGC_WRITE_REG(hw, IGC_DVMOLR(rxq->reg_idx), dvmolr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -2107,3 +2117,31 @@ eth_igc_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
|
|||||||
qinfo->conf.tx_thresh.wthresh = txq->wthresh;
|
qinfo->conf.tx_thresh.wthresh = txq->wthresh;
|
||||||
qinfo->conf.offloads = txq->offloads;
|
qinfo->conf.offloads = txq->offloads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
eth_igc_vlan_strip_queue_set(struct rte_eth_dev *dev,
|
||||||
|
uint16_t rx_queue_id, int on)
|
||||||
|
{
|
||||||
|
struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
|
||||||
|
struct igc_rx_queue *rxq = dev->data->rx_queues[rx_queue_id];
|
||||||
|
uint32_t reg_val;
|
||||||
|
|
||||||
|
if (rx_queue_id >= IGC_QUEUE_PAIRS_NUM) {
|
||||||
|
PMD_DRV_LOG(ERR, "Queue index(%u) illegal, max is %u",
|
||||||
|
rx_queue_id, IGC_QUEUE_PAIRS_NUM - 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_val = IGC_READ_REG(hw, IGC_DVMOLR(rx_queue_id));
|
||||||
|
if (on) {
|
||||||
|
/* If vlan been stripped off, the CRC is meaningless. */
|
||||||
|
reg_val |= IGC_DVMOLR_STRVLAN | IGC_DVMOLR_STRCRC;
|
||||||
|
rxq->offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
|
||||||
|
} else {
|
||||||
|
reg_val &= ~(IGC_DVMOLR_STRVLAN | IGC_DVMOLR_HIDVLAN |
|
||||||
|
IGC_DVMOLR_STRCRC);
|
||||||
|
rxq->offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
IGC_WRITE_REG(hw, IGC_DVMOLR(rx_queue_id), reg_val);
|
||||||
|
}
|
||||||
|
@ -44,7 +44,8 @@ void eth_igc_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
|
|||||||
struct rte_eth_rxq_info *qinfo);
|
struct rte_eth_rxq_info *qinfo);
|
||||||
void eth_igc_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
|
void eth_igc_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
|
||||||
struct rte_eth_txq_info *qinfo);
|
struct rte_eth_txq_info *qinfo);
|
||||||
|
void eth_igc_vlan_strip_queue_set(struct rte_eth_dev *dev,
|
||||||
|
uint16_t rx_queue_id, int on);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user