ixgbe: configure VF RSS
[dpdk.git] / lib / librte_pmd_ixgbe / ixgbe_rxtx.c
index 61ffc4f..840bc07 100644 (file)
@@ -3339,6 +3339,67 @@ ixgbe_alloc_rx_queue_mbufs(struct igb_rx_queue *rxq)
        return 0;
 }
 
+static int
+ixgbe_config_vf_rss(struct rte_eth_dev *dev)
+{
+       struct ixgbe_hw *hw;
+       uint32_t mrqc;
+
+       ixgbe_rss_configure(dev);
+
+       hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+       /* MRQC: enable VF RSS */
+       mrqc = IXGBE_READ_REG(hw, IXGBE_MRQC);
+       mrqc &= ~IXGBE_MRQC_MRQE_MASK;
+       switch (RTE_ETH_DEV_SRIOV(dev).active) {
+       case ETH_64_POOLS:
+               mrqc |= IXGBE_MRQC_VMDQRSS64EN;
+               break;
+
+       case ETH_32_POOLS:
+               mrqc |= IXGBE_MRQC_VMDQRSS32EN;
+               break;
+
+       default:
+               PMD_INIT_LOG(ERR, "Invalid pool number in IOV mode with VMDQ RSS");
+               return -EINVAL;
+       }
+
+       IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
+
+       return 0;
+}
+
+static int
+ixgbe_config_vf_default(struct rte_eth_dev *dev)
+{
+       struct ixgbe_hw *hw =
+               IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+       switch (RTE_ETH_DEV_SRIOV(dev).active) {
+       case ETH_64_POOLS:
+               IXGBE_WRITE_REG(hw, IXGBE_MRQC,
+                       IXGBE_MRQC_VMDQEN);
+               break;
+
+       case ETH_32_POOLS:
+               IXGBE_WRITE_REG(hw, IXGBE_MRQC,
+                       IXGBE_MRQC_VMDQRT4TCEN);
+               break;
+
+       case ETH_16_POOLS:
+               IXGBE_WRITE_REG(hw, IXGBE_MRQC,
+                       IXGBE_MRQC_VMDQRT8TCEN);
+               break;
+       default:
+               PMD_INIT_LOG(ERR,
+                       "invalid pool number in IOV mode");
+               break;
+       }
+       return 0;
+}
+
 static int
 ixgbe_dev_mq_rx_configure(struct rte_eth_dev *dev)
 {
@@ -3371,24 +3432,25 @@ ixgbe_dev_mq_rx_configure(struct rte_eth_dev *dev)
                        default: ixgbe_rss_disable(dev);
                }
        } else {
-               switch (RTE_ETH_DEV_SRIOV(dev).active) {
                /*
                 * SRIOV active scheme
-                * FIXME if support DCB/RSS together with VMDq & SRIOV
+                * Support RSS together with VMDq & SRIOV
                 */
-               case ETH_64_POOLS:
-                       IXGBE_WRITE_REG(hw, IXGBE_MRQC, IXGBE_MRQC_VMDQEN);
-                       break;
-
-               case ETH_32_POOLS:
-                       IXGBE_WRITE_REG(hw, IXGBE_MRQC, IXGBE_MRQC_VMDQRT4TCEN);
+               switch (dev->data->dev_conf.rxmode.mq_mode) {
+               case ETH_MQ_RX_RSS:
+               case ETH_MQ_RX_VMDQ_RSS:
+                       ixgbe_config_vf_rss(dev);
                        break;
 
-               case ETH_16_POOLS:
-                       IXGBE_WRITE_REG(hw, IXGBE_MRQC, IXGBE_MRQC_VMDQRT8TCEN);
-                       break;
+               /* FIXME if support DCB/RSS together with VMDq & SRIOV */
+               case ETH_MQ_RX_VMDQ_DCB:
+               case ETH_MQ_RX_VMDQ_DCB_RSS:
+                       PMD_INIT_LOG(ERR,
+                               "Could not support DCB with VMDq & SRIOV");
+                       return -1;
                default:
-                       PMD_INIT_LOG(ERR, "invalid pool number in IOV mode");
+                       ixgbe_config_vf_default(dev);
+                       break;
                }
        }
 
@@ -4006,6 +4068,19 @@ ixgbevf_dev_rx_init(struct rte_eth_dev *dev)
        PMD_INIT_FUNC_TRACE();
        hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
+       if (rte_is_power_of_2(dev->data->nb_rx_queues) == 0) {
+               PMD_INIT_LOG(ERR, "The number of Rx queue invalid, "
+                       "it should be power of 2");
+               return -1;
+       }
+
+       if (dev->data->nb_rx_queues > hw->mac.max_rx_queues) {
+               PMD_INIT_LOG(ERR, "The number of Rx queue invalid, "
+                       "it should be equal to or less than %d",
+                       hw->mac.max_rx_queues);
+               return -1;
+       }
+
        /*
         * When the VF driver issues a IXGBE_VF_RESET request, the PF driver
         * disables the VF receipt of packets if the PF MTU is > 1500.
@@ -4107,6 +4182,9 @@ ixgbevf_dev_rx_init(struct rte_eth_dev *dev)
                        IXGBE_PSRTYPE_IPV6HDR;
 #endif
 
+       /* Set RQPL for VF RSS according to max Rx queue */
+       psrtype |= (dev->data->nb_rx_queues >> 1) <<
+               IXGBE_PSRTYPE_RQPL_SHIFT;
        IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype);
 
        if (dev->data->dev_conf.rxmode.enable_scatter) {