net/ixgbe: support VLAN strip per queue offloading in PF
authorWei Dai <wei.dai@intel.com>
Thu, 22 Mar 2018 03:41:00 +0000 (11:41 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 13 Apr 2018 22:40:21 +0000 (00:40 +0200)
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>
drivers/net/ixgbe/ixgbe_ethdev.c
drivers/net/ixgbe/ixgbe_ethdev.h
drivers/net/ixgbe/ixgbe_pf.c
drivers/net/ixgbe/ixgbe_rxtx.c
drivers/net/ixgbe/ixgbe_rxtx.h

index 4df5c75..b3b4631 100644 (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) {
index c56d652..6550777 100644 (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);
 
index ea99737..4e61310 100644 (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
index 6c582b4..5c45eb4 100644 (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.
index 69c718b..ab5f01e 100644 (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 */