net/ixgbe: support VLAN strip per queue offloading in PF

VLAN strip is a per queue offloading in PF. With this patch
it can be enabled or disabled on any Rx queue in PF.

Signed-off-by: Wei Dai <wei.dai@intel.com>
Acked-by: Qi Zhang <qi.z.zhang@intel.com>
This commit is contained in:
Wei Dai 2018-03-22 11:41:00 +08:00 committed by Ferruh Yigit
parent 7497d3e2f7
commit 216f78f4d5
5 changed files with 51 additions and 69 deletions

View File

@ -1962,64 +1962,6 @@ ixgbe_vlan_hw_strip_enable(struct rte_eth_dev *dev, uint16_t queue)
ixgbe_vlan_hw_strip_bitmap_set(dev, queue, 1);
}
void
ixgbe_vlan_hw_strip_disable_all(struct rte_eth_dev *dev)
{
struct ixgbe_hw *hw =
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint32_t ctrl;
uint16_t i;
struct ixgbe_rx_queue *rxq;
PMD_INIT_FUNC_TRACE();
if (hw->mac.type == ixgbe_mac_82598EB) {
ctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
ctrl &= ~IXGBE_VLNCTRL_VME;
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, ctrl);
} else {
/* Other 10G NIC, the VLAN strip can be setup per queue in RXDCTL */
for (i = 0; i < dev->data->nb_rx_queues; i++) {
rxq = dev->data->rx_queues[i];
ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxq->reg_idx));
ctrl &= ~IXGBE_RXDCTL_VME;
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rxq->reg_idx), ctrl);
/* record those setting for HW strip per queue */
ixgbe_vlan_hw_strip_bitmap_set(dev, i, 0);
}
}
}
void
ixgbe_vlan_hw_strip_enable_all(struct rte_eth_dev *dev)
{
struct ixgbe_hw *hw =
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint32_t ctrl;
uint16_t i;
struct ixgbe_rx_queue *rxq;
PMD_INIT_FUNC_TRACE();
if (hw->mac.type == ixgbe_mac_82598EB) {
ctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
ctrl |= IXGBE_VLNCTRL_VME;
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, ctrl);
} else {
/* Other 10G NIC, the VLAN strip can be setup per queue in RXDCTL */
for (i = 0; i < dev->data->nb_rx_queues; i++) {
rxq = dev->data->rx_queues[i];
ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxq->reg_idx));
ctrl |= IXGBE_RXDCTL_VME;
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rxq->reg_idx), ctrl);
/* record those setting for HW strip per queue */
ixgbe_vlan_hw_strip_bitmap_set(dev, i, 1);
}
}
}
static void
ixgbe_vlan_hw_extend_disable(struct rte_eth_dev *dev)
{
@ -2075,14 +2017,57 @@ ixgbe_vlan_hw_extend_enable(struct rte_eth_dev *dev)
*/
}
void
ixgbe_vlan_hw_strip_config(struct rte_eth_dev *dev)
{
struct ixgbe_hw *hw =
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
uint32_t ctrl;
uint16_t i;
struct ixgbe_rx_queue *rxq;
bool on;
PMD_INIT_FUNC_TRACE();
if (hw->mac.type == ixgbe_mac_82598EB) {
if (rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) {
ctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
ctrl |= IXGBE_VLNCTRL_VME;
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, ctrl);
} else {
ctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
ctrl &= ~IXGBE_VLNCTRL_VME;
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, ctrl);
}
} else {
/*
* Other 10G NIC, the VLAN strip can be setup
* per queue in RXDCTL
*/
for (i = 0; i < dev->data->nb_rx_queues; i++) {
rxq = dev->data->rx_queues[i];
ctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rxq->reg_idx));
if (rxq->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) {
ctrl |= IXGBE_RXDCTL_VME;
on = TRUE;
} else {
ctrl &= ~IXGBE_RXDCTL_VME;
on = FALSE;
}
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rxq->reg_idx), ctrl);
/* record those setting for HW strip per queue */
ixgbe_vlan_hw_strip_bitmap_set(dev, i, on);
}
}
}
static int
ixgbe_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
if (mask & ETH_VLAN_STRIP_MASK) {
if (dev->data->dev_conf.rxmode.hw_vlan_strip)
ixgbe_vlan_hw_strip_enable_all(dev);
else
ixgbe_vlan_hw_strip_disable_all(dev);
ixgbe_vlan_hw_strip_config(dev);
}
if (mask & ETH_VLAN_FILTER_MASK) {

View File

@ -659,9 +659,7 @@ void ixgbe_vlan_hw_filter_enable(struct rte_eth_dev *dev);
void ixgbe_vlan_hw_filter_disable(struct rte_eth_dev *dev);
void ixgbe_vlan_hw_strip_enable_all(struct rte_eth_dev *dev);
void ixgbe_vlan_hw_strip_disable_all(struct rte_eth_dev *dev);
void ixgbe_vlan_hw_strip_config(struct rte_eth_dev *dev);
void ixgbe_pf_host_init(struct rte_eth_dev *eth_dev);

View File

@ -329,10 +329,7 @@ set_rx_mode(struct rte_eth_dev *dev)
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
if (dev->data->dev_conf.rxmode.hw_vlan_strip)
ixgbe_vlan_hw_strip_enable_all(dev);
else
ixgbe_vlan_hw_strip_disable_all(dev);
ixgbe_vlan_hw_strip_config(dev);
}
static inline void

View File

@ -2820,6 +2820,7 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
0 : ETHER_CRC_LEN);
rxq->drop_en = rx_conf->rx_drop_en;
rxq->rx_deferred_start = rx_conf->rx_deferred_start;
rxq->offloads = rx_conf->offloads;
/*
* The packet type in RX descriptor is different for different NICs.

View File

@ -129,6 +129,7 @@ struct ixgbe_rx_queue {
uint8_t rx_deferred_start; /**< not in global dev start. */
/** flags to set in mbuf when a vlan is detected. */
uint64_t vlan_flags;
uint64_t offloads; /**< Rx offloads with DEV_RX_OFFLOAD_* */
/** need to alloc dummy mbuf, for wraparound when scanning hw ring */
struct rte_mbuf fake_mbuf;
/** hold packets to return to application */