pci: make device id tables const
[dpdk.git] / lib / librte_pmd_i40e / i40e_ethdev.c
index 3a59f84..43762f2 100644 (file)
        (1UL << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER) | \
        (1UL << RTE_ETH_FLOW_L2_PAYLOAD))
 
-static int eth_i40e_dev_init(\
-                       __attribute__((unused)) struct eth_driver *eth_drv,
-                       struct rte_eth_dev *eth_dev);
+static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev);
 static int i40e_dev_configure(struct rte_eth_dev *dev);
 static int i40e_dev_start(struct rte_eth_dev *dev);
 static void i40e_dev_stop(struct rte_eth_dev *dev);
@@ -214,13 +212,13 @@ static int i40e_dev_filter_ctrl(struct rte_eth_dev *dev,
 static void i40e_configure_registers(struct i40e_hw *hw);
 static void i40e_hw_init(struct i40e_hw *hw);
 
-static struct rte_pci_id pci_id_i40e_map[] = {
+static const struct rte_pci_id pci_id_i40e_map[] = {
 #define RTE_PCI_DEV_ID_DECL_I40E(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
 #include "rte_pci_dev_ids.h"
 { .vendor_id = 0, /* sentinel */ },
 };
 
-static struct eth_dev_ops i40e_eth_dev_ops = {
+static const struct eth_dev_ops i40e_eth_dev_ops = {
        .dev_configure                = i40e_dev_configure,
        .dev_start                    = i40e_dev_start,
        .dev_stop                     = i40e_dev_stop,
@@ -364,8 +362,7 @@ static inline void i40e_flex_payload_reg_init(struct i40e_hw *hw)
 }
 
 static int
-eth_i40e_dev_init(__rte_unused struct eth_driver *eth_drv,
-                  struct rte_eth_dev *dev)
+eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
        struct rte_pci_device *pci_dev;
        struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
@@ -1084,28 +1081,37 @@ i40e_dev_set_link_down(__rte_unused struct rte_eth_dev *dev)
 
 int
 i40e_dev_link_update(struct rte_eth_dev *dev,
-                    __rte_unused int wait_to_complete)
+                    int wait_to_complete)
 {
+#define CHECK_INTERVAL 100  /* 100ms */
+#define MAX_REPEAT_TIME 10  /* 1s (10 * 100ms) in total */
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct i40e_link_status link_status;
        struct rte_eth_link link, old;
        int status;
+       unsigned rep_cnt = MAX_REPEAT_TIME;
 
        memset(&link, 0, sizeof(link));
        memset(&old, 0, sizeof(old));
        memset(&link_status, 0, sizeof(link_status));
        rte_i40e_dev_atomic_read_link_status(dev, &old);
 
-       /* Get link status information from hardware */
-       status = i40e_aq_get_link_info(hw, false, &link_status, NULL);
-       if (status != I40E_SUCCESS) {
-               link.link_speed = ETH_LINK_SPEED_100;
-               link.link_duplex = ETH_LINK_FULL_DUPLEX;
-               PMD_DRV_LOG(ERR, "Failed to get link info");
-               goto out;
-       }
+       do {
+               /* Get link status information from hardware */
+               status = i40e_aq_get_link_info(hw, false, &link_status, NULL);
+               if (status != I40E_SUCCESS) {
+                       link.link_speed = ETH_LINK_SPEED_100;
+                       link.link_duplex = ETH_LINK_FULL_DUPLEX;
+                       PMD_DRV_LOG(ERR, "Failed to get link info");
+                       goto out;
+               }
+
+               link.link_status = link_status.link_info & I40E_AQ_LINK_UP;
+               if (!wait_to_complete)
+                       break;
 
-       link.link_status = link_status.link_info & I40E_AQ_LINK_UP;
+               rte_delay_ms(CHECK_INTERVAL);
+       } while (!link.link_status && rep_cnt--);
 
        if (!link.link_status)
                goto out;
@@ -1531,8 +1537,10 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
                DEV_TX_OFFLOAD_UDP_CKSUM |
                DEV_TX_OFFLOAD_TCP_CKSUM |
                DEV_TX_OFFLOAD_SCTP_CKSUM |
-               DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
+               DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
+               DEV_TX_OFFLOAD_TCP_TSO;
        dev_info->reta_size = pf->hash_lut_size;
+       dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL;
 
        dev_info->default_rxconf = (struct rte_eth_rxconf) {
                .rx_thresh = {
@@ -2647,7 +2655,7 @@ i40e_vsi_config_tc_queue_mapping(struct i40e_vsi *vsi,
                        rte_cpu_to_le_16(I40E_AQ_VSI_QUE_MAP_CONTIG);
                info->queue_mapping[0] = rte_cpu_to_le_16(vsi->base_queue);
        }
-       info->valid_sections =
+       info->valid_sections |=
                rte_cpu_to_le_16(I40E_AQ_VSI_PROP_QUEUE_MAP_VALID);
 
        return I40E_SUCCESS;
@@ -3060,11 +3068,15 @@ i40e_vsi_setup(struct i40e_pf *pf,
                ctxt.connection_type = 0x1;
                ctxt.flags = I40E_AQ_VSI_TYPE_VF;
 
-               /* Configure switch ID */
-               ctxt.info.valid_sections |=
-                       rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SWITCH_VALID);
-               ctxt.info.switch_id =
-                       rte_cpu_to_le_16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
+               /**
+                * Do not configure switch ID to enable VEB switch by
+                * I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB. Because in Fortville,
+                * if the source mac address of packet sent from VF is not
+                * listed in the VEB's mac table, the VEB will switch the
+                * packet back to the VF. Need to enable it when HW issue
+                * is fixed.
+                */
+
                /* Configure port/vlan */
                ctxt.info.valid_sections |=
                        rte_cpu_to_le_16(I40E_AQ_VSI_PROP_VLAN_VALID);
@@ -3121,6 +3133,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
                ctxt.info.valid_sections |=
                        rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SCHED_VALID);
        } else if (type == I40E_VSI_FDIR) {
+               memset(&ctxt, 0, sizeof(ctxt));
                vsi->uplink_seid = uplink_vsi->uplink_seid;
                ctxt.pf_num = hw->pf_id;
                ctxt.vf_num = 0;
@@ -3144,7 +3157,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
 
        if (vsi->type != I40E_VSI_MAIN) {
                ret = i40e_aq_add_vsi(hw, &ctxt, NULL);
-               if (ret) {
+               if (ret != I40E_SUCCESS) {
                        PMD_DRV_LOG(ERR, "add vsi failed, aq_err=%d",
                                    hw->aq.asq_last_status);
                        goto fail_msix_alloc;
@@ -4589,26 +4602,26 @@ i40e_config_hena(uint64_t flags)
        if (!flags)
                return hena;
 
-       if (flags & ETH_RSS_NONF_IPV4_UDP)
-               hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
-       if (flags & ETH_RSS_NONF_IPV4_TCP)
+       if (flags & ETH_RSS_FRAG_IPV4)
+               hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4;
+       if (flags & ETH_RSS_NONFRAG_IPV4_TCP)
                hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
-       if (flags & ETH_RSS_NONF_IPV4_SCTP)
+       if (flags & ETH_RSS_NONFRAG_IPV4_UDP)
+               hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
+       if (flags & ETH_RSS_NONFRAG_IPV4_SCTP)
                hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP;
-       if (flags & ETH_RSS_NONF_IPV4_OTHER)
+       if (flags & ETH_RSS_NONFRAG_IPV4_OTHER)
                hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER;
-       if (flags & ETH_RSS_FRAG_IPV4)
-               hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4;
-       if (flags & ETH_RSS_NONF_IPV6_UDP)
-               hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP;
-       if (flags & ETH_RSS_NONF_IPV6_TCP)
+       if (flags & ETH_RSS_FRAG_IPV6)
+               hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6;
+       if (flags & ETH_RSS_NONFRAG_IPV6_TCP)
                hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP;
-       if (flags & ETH_RSS_NONF_IPV6_SCTP)
+       if (flags & ETH_RSS_NONFRAG_IPV6_UDP)
+               hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP;
+       if (flags & ETH_RSS_NONFRAG_IPV6_SCTP)
                hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP;
-       if (flags & ETH_RSS_NONF_IPV6_OTHER)
+       if (flags & ETH_RSS_NONFRAG_IPV6_OTHER)
                hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER;
-       if (flags & ETH_RSS_FRAG_IPV6)
-               hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6;
        if (flags & ETH_RSS_L2_PAYLOAD)
                hena |= 1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD;
 
@@ -4623,27 +4636,26 @@ i40e_parse_hena(uint64_t flags)
 
        if (!flags)
                return rss_hf;
-
-       if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP))
-               rss_hf |= ETH_RSS_NONF_IPV4_UDP;
+       if (flags & (1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4))
+               rss_hf |= ETH_RSS_FRAG_IPV4;
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP))
-               rss_hf |= ETH_RSS_NONF_IPV4_TCP;
+               rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
+       if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP))
+               rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP))
-               rss_hf |= ETH_RSS_NONF_IPV4_SCTP;
+               rss_hf |= ETH_RSS_NONFRAG_IPV4_SCTP;
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER))
-               rss_hf |= ETH_RSS_NONF_IPV4_OTHER;
-       if (flags & (1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4))
-               rss_hf |= ETH_RSS_FRAG_IPV4;
-       if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP))
-               rss_hf |= ETH_RSS_NONF_IPV6_UDP;
+               rss_hf |= ETH_RSS_NONFRAG_IPV4_OTHER;
+       if (flags & (1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6))
+               rss_hf |= ETH_RSS_FRAG_IPV6;
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP))
-               rss_hf |= ETH_RSS_NONF_IPV6_TCP;
+               rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
+       if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP))
+               rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP))
-               rss_hf |= ETH_RSS_NONF_IPV6_SCTP;
+               rss_hf |= ETH_RSS_NONFRAG_IPV6_SCTP;
        if (flags & (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER))
-               rss_hf |= ETH_RSS_NONF_IPV6_OTHER;
-       if (flags & (1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6))
-               rss_hf |= ETH_RSS_FRAG_IPV6;
+               rss_hf |= ETH_RSS_NONFRAG_IPV6_OTHER;
        if (flags & (1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD))
                rss_hf |= ETH_RSS_L2_PAYLOAD;
 
@@ -4811,6 +4823,9 @@ i40e_dev_tunnel_filter_set(struct i40e_pf *pf,
        case RTE_TUNNEL_TYPE_VXLAN:
                tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_XVLAN;
                break;
+       case RTE_TUNNEL_TYPE_NVGRE:
+               tun_type = I40E_AQC_ADD_CLOUD_TNL_TYPE_NVGRE_OMAC;
+               break;
        default:
                /* Other tunnel types is not supported. */
                PMD_DRV_LOG(ERR, "tunnel type is not supported.");
@@ -5628,38 +5643,54 @@ i40e_debug_read_register(struct i40e_hw *hw, uint32_t addr, uint64_t *val)
 
 /*
  * On X710, performance number is far from the expectation on recent firmware
- * versions. The fix for this issue may not be integrated in the following
+ * versions; on XL710, performance number is also far from the expectation on
+ * recent firmware versions, if promiscuous mode is disabled, or promiscuous
+ * mode is enabled and port MAC address is equal to the packet destination MAC
+ * address. The fix for this issue may not be integrated in the following
  * firmware version. So the workaround in software driver is needed. It needs
- * to modify the initial values of 3 internal only registers. Note that the
+ * to modify the initial values of 3 internal only registers for both X710 and
+ * XL710. Note that the values for X710 or XL710 could be different, and the
  * workaround can be removed when it is fixed in firmware in the future.
  */
-static void
-i40e_configure_registers(struct i40e_hw *hw)
-{
+
+/* For both X710 and XL710 */
+#define I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE 0x10000200
 #define I40E_GL_SWR_PRI_JOIN_MAP_0       0x26CE00
+
+#define I40E_GL_SWR_PRI_JOIN_MAP_2_VALUE 0x011f0200
 #define I40E_GL_SWR_PRI_JOIN_MAP_2       0x26CE08
+
+/* For X710 */
+#define I40E_GL_SWR_PM_UP_THR_EF_VALUE   0x03030303
+/* For XL710 */
+#define I40E_GL_SWR_PM_UP_THR_SF_VALUE   0x06060606
 #define I40E_GL_SWR_PM_UP_THR            0x269FBC
-#define I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE 0x10000200
-#define I40E_GL_SWR_PRI_JOIN_MAP_2_VALUE 0x011f0200
-#define I40E_GL_SWR_PM_UP_THR_VALUE      0x03030303
 
-       static const struct {
+static void
+i40e_configure_registers(struct i40e_hw *hw)
+{
+       static struct {
                uint32_t addr;
                uint64_t val;
        } reg_table[] = {
                {I40E_GL_SWR_PRI_JOIN_MAP_0, I40E_GL_SWR_PRI_JOIN_MAP_0_VALUE},
                {I40E_GL_SWR_PRI_JOIN_MAP_2, I40E_GL_SWR_PRI_JOIN_MAP_2_VALUE},
-               {I40E_GL_SWR_PM_UP_THR, I40E_GL_SWR_PM_UP_THR_VALUE},
+               {I40E_GL_SWR_PM_UP_THR, 0}, /* Compute value dynamically */
        };
        uint64_t reg;
        uint32_t i;
        int ret;
 
-       /* Below fix is for X710 only */
-       if (i40e_is_40G_device(hw->device_id))
-               return;
-
        for (i = 0; i < RTE_DIM(reg_table); i++) {
+               if (reg_table[i].addr == I40E_GL_SWR_PM_UP_THR) {
+                       if (i40e_is_40G_device(hw->device_id)) /* For XL710 */
+                               reg_table[i].val =
+                                       I40E_GL_SWR_PM_UP_THR_SF_VALUE;
+                       else /* For X710 */
+                               reg_table[i].val =
+                                       I40E_GL_SWR_PM_UP_THR_EF_VALUE;
+               }
+
                ret = i40e_debug_read_register(hw, reg_table[i].addr, &reg);
                if (ret < 0) {
                        PMD_DRV_LOG(ERR, "Failed to read from 0x%"PRIx32,