New upstream version 16.11.3
[deb_dpdk.git] / drivers / net / mlx4 / mlx4.c
index 304c846..4a03d34 100644 (file)
 /* Verbs header. */
 /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
 #ifdef PEDANTIC
-#pragma GCC diagnostic ignored "-pedantic"
+#pragma GCC diagnostic ignored "-Wpedantic"
 #endif
 #include <infiniband/verbs.h>
 #ifdef PEDANTIC
-#pragma GCC diagnostic error "-pedantic"
+#pragma GCC diagnostic error "-Wpedantic"
 #endif
 
 /* DPDK headers don't like -pedantic. */
 #ifdef PEDANTIC
-#pragma GCC diagnostic ignored "-pedantic"
+#pragma GCC diagnostic ignored "-Wpedantic"
 #endif
 #include <rte_ether.h>
 #include <rte_ethdev.h>
@@ -87,7 +87,7 @@
 #include <rte_alarm.h>
 #include <rte_memory.h>
 #ifdef PEDANTIC
-#pragma GCC diagnostic error "-pedantic"
+#pragma GCC diagnostic error "-Wpedantic"
 #endif
 
 /* Generated configuration header. */
@@ -2961,19 +2961,25 @@ rxq_cq_to_pkt_type(uint32_t flags)
        if (flags & IBV_EXP_CQ_RX_TUNNEL_PACKET)
                pkt_type =
                        TRANSPOSE(flags,
-                                 IBV_EXP_CQ_RX_OUTER_IPV4_PACKET, RTE_PTYPE_L3_IPV4) |
+                                 IBV_EXP_CQ_RX_OUTER_IPV4_PACKET,
+                                 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN) |
                        TRANSPOSE(flags,
-                                 IBV_EXP_CQ_RX_OUTER_IPV6_PACKET, RTE_PTYPE_L3_IPV6) |
+                                 IBV_EXP_CQ_RX_OUTER_IPV6_PACKET,
+                                 RTE_PTYPE_L3_IPV6_EXT_UNKNOWN) |
                        TRANSPOSE(flags,
-                                 IBV_EXP_CQ_RX_IPV4_PACKET, RTE_PTYPE_INNER_L3_IPV4) |
+                                 IBV_EXP_CQ_RX_IPV4_PACKET,
+                                 RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN) |
                        TRANSPOSE(flags,
-                                 IBV_EXP_CQ_RX_IPV6_PACKET, RTE_PTYPE_INNER_L3_IPV6);
+                                 IBV_EXP_CQ_RX_IPV6_PACKET,
+                                 RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN);
        else
                pkt_type =
                        TRANSPOSE(flags,
-                                 IBV_EXP_CQ_RX_IPV4_PACKET, RTE_PTYPE_L3_IPV4) |
+                                 IBV_EXP_CQ_RX_IPV4_PACKET,
+                                 RTE_PTYPE_L3_IPV4_EXT_UNKNOWN) |
                        TRANSPOSE(flags,
-                                 IBV_EXP_CQ_RX_IPV6_PACKET, RTE_PTYPE_L3_IPV6);
+                                 IBV_EXP_CQ_RX_IPV6_PACKET,
+                                 RTE_PTYPE_L3_IPV6_EXT_UNKNOWN);
        return pkt_type;
 }
 
@@ -2995,25 +3001,20 @@ rxq_cq_to_ol_flags(const struct rxq *rxq, uint32_t flags)
 
        if (rxq->csum)
                ol_flags |=
-                       TRANSPOSE(~flags,
+                       TRANSPOSE(flags,
                                  IBV_EXP_CQ_RX_IP_CSUM_OK,
-                                 PKT_RX_IP_CKSUM_BAD) |
-                       TRANSPOSE(~flags,
+                                 PKT_RX_IP_CKSUM_GOOD) |
+                       TRANSPOSE(flags,
                                  IBV_EXP_CQ_RX_TCP_UDP_CSUM_OK,
-                                 PKT_RX_L4_CKSUM_BAD);
-       /*
-        * PKT_RX_IP_CKSUM_BAD and PKT_RX_L4_CKSUM_BAD are used in place
-        * of PKT_RX_EIP_CKSUM_BAD because the latter is not functional
-        * (its value is 0).
-        */
+                                 PKT_RX_L4_CKSUM_GOOD);
        if ((flags & IBV_EXP_CQ_RX_TUNNEL_PACKET) && (rxq->csum_l2tun))
                ol_flags |=
-                       TRANSPOSE(~flags,
+                       TRANSPOSE(flags,
                                  IBV_EXP_CQ_RX_OUTER_IP_CSUM_OK,
-                                 PKT_RX_IP_CKSUM_BAD) |
-                       TRANSPOSE(~flags,
+                                 PKT_RX_IP_CKSUM_GOOD) |
+                       TRANSPOSE(flags,
                                  IBV_EXP_CQ_RX_OUTER_TCP_UDP_CSUM_OK,
-                                 PKT_RX_L4_CKSUM_BAD);
+                                 PKT_RX_L4_CKSUM_GOOD);
        return ol_flags;
 }
 
@@ -3156,6 +3157,13 @@ mlx4_rx_burst_sp(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
                        NB_SEGS(rep) = 0x2a;
                        PORT(rep) = 0x2a;
                        rep->ol_flags = -1;
+                       /*
+                        * Clear special flags in mbuf to avoid
+                        * crashing while freeing.
+                        */
+                       rep->ol_flags &=
+                               ~(uint64_t)(IND_ATTACHED_MBUF |
+                                           CTRL_MBUF_FLAG);
 #endif
                        assert(rep->buf_len == seg->buf_len);
                        /* Reconfigure sge to use rep instead of seg. */
@@ -3339,6 +3347,8 @@ mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n)
                        /* Increase out of memory counters. */
                        ++rxq->stats.rx_nombuf;
                        ++rxq->priv->dev->data->rx_mbuf_alloc_failed;
+                       /* Add SGE to array for repost. */
+                       sges[i] = elt->sge;
                        goto repost;
                }
 
@@ -5448,7 +5458,7 @@ mlx4_dev_link_status_handler(void *arg)
        ret = priv_dev_link_status_handler(priv, dev);
        priv_unlock(priv);
        if (ret)
-               _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+               _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
 }
 
 /**
@@ -5471,7 +5481,7 @@ mlx4_dev_interrupt_handler(struct rte_intr_handle *intr_handle, void *cb_arg)
        ret = priv_dev_link_status_handler(priv, dev);
        priv_unlock(priv);
        if (ret)
-               _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC);
+               _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
 }
 
 /**
@@ -5544,7 +5554,7 @@ static struct eth_driver mlx4_driver;
  *   0 on success, negative errno value on failure.
  */
 static int
-mlx4_pci_devinit(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
+mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 {
        struct ibv_device **list;
        struct ibv_device *ibv_dev;
@@ -5570,10 +5580,8 @@ mlx4_pci_devinit(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
        list = ibv_get_device_list(&i);
        if (list == NULL) {
                assert(errno);
-               if (errno == ENOSYS) {
-                       WARN("cannot list devices, is ib_uverbs loaded?");
-                       return 0;
-               }
+               if (errno == ENOSYS)
+                       ERROR("cannot list devices, is ib_uverbs loaded?");
                return -errno;
        }
        assert(i >= 0);
@@ -5605,11 +5613,11 @@ mlx4_pci_devinit(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                ibv_free_device_list(list);
                switch (err) {
                case 0:
-                       WARN("cannot access device, is mlx4_ib loaded?");
-                       return 0;
+                       ERROR("cannot access device, is mlx4_ib loaded?");
+                       return -ENODEV;
                case EINVAL:
-                       WARN("cannot use device, are drivers up to date?");
-                       return 0;
+                       ERROR("cannot use device, are drivers up to date?");
+                       return -EINVAL;
                }
                assert(err > 0);
                return -err;
@@ -5617,8 +5625,10 @@ mlx4_pci_devinit(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
        ibv_dev = list[i];
 
        DEBUG("device opened");
-       if (ibv_query_device(attr_ctx, &device_attr))
+       if (ibv_query_device(attr_ctx, &device_attr)) {
+               err = EINVAL;
                goto error;
+       }
        INFO("%u port(s) detected", device_attr.phys_port_cnt);
 
        for (i = 0; i < device_attr.phys_port_cnt; i++) {
@@ -5644,19 +5654,23 @@ mlx4_pci_devinit(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                DEBUG("using port %u (%08" PRIx32 ")", port, test);
 
                ctx = ibv_open_device(ibv_dev);
-               if (ctx == NULL)
+               if (ctx == NULL) {
+                       err = ENODEV;
                        goto port_error;
+               }
 
                /* Check port status. */
                err = ibv_query_port(ctx, port, &port_attr);
                if (err) {
                        ERROR("port query failed: %s", strerror(err));
+                       err = ENODEV;
                        goto port_error;
                }
 
                if (port_attr.link_layer != IBV_LINK_LAYER_ETHERNET) {
                        ERROR("port %d is not configured in Ethernet mode",
                              port);
+                       err = EINVAL;
                        goto port_error;
                }
 
@@ -5693,6 +5707,7 @@ mlx4_pci_devinit(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 #ifdef HAVE_EXP_QUERY_DEVICE
                if (ibv_exp_query_device(ctx, &exp_device_attr)) {
                        ERROR("ibv_exp_query_device() failed");
+                       err = ENODEV;
                        goto port_error;
                }
 #ifdef RSS_SUPPORT
@@ -5768,6 +5783,7 @@ mlx4_pci_devinit(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                if (priv_get_mac(priv, &mac.addr_bytes)) {
                        ERROR("cannot get MAC address, is mlx4_en loaded?"
                              " (errno: %s)", strerror(errno));
+                       err = ENODEV;
                        goto port_error;
                }
                INFO("port %u MAC address is %02x:%02x:%02x:%02x:%02x:%02x",
@@ -5803,7 +5819,7 @@ mlx4_pci_devinit(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 
                        snprintf(name, sizeof(name), "%s port %u",
                                 ibv_get_device_name(ibv_dev), port);
-                       eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_PCI);
+                       eth_dev = rte_eth_dev_allocate(name);
                }
                if (eth_dev == NULL) {
                        ERROR("can not allocate rte ethdev");
@@ -5856,6 +5872,9 @@ mlx4_pci_devinit(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
                /* Bring Ethernet device up. */
                DEBUG("forcing Ethernet interface up");
                priv_set_flags(priv, ~IFF_UP, IFF_UP);
+               /* Update link status once if waiting for LSC. */
+               if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
+                       mlx4_link_update(eth_dev, 0);
                continue;
 
 port_error:
@@ -5911,9 +5930,11 @@ static const struct rte_pci_id mlx4_pci_id_map[] = {
 
 static struct eth_driver mlx4_driver = {
        .pci_drv = {
-               .name = MLX4_DRIVER_NAME,
+               .driver = {
+                       .name = MLX4_DRIVER_NAME
+               },
                .id_table = mlx4_pci_id_map,
-               .devinit = mlx4_pci_devinit,
+               .probe = mlx4_pci_probe,
                .drv_flags = RTE_PCI_DRV_INTR_LSC,
        },
        .dev_private_size = sizeof(struct priv)
@@ -5922,12 +5943,10 @@ static struct eth_driver mlx4_driver = {
 /**
  * Driver initialization routine.
  */
-static int
-rte_mlx4_pmd_init(const char *name, const char *args)
+RTE_INIT(rte_mlx4_pmd_init);
+static void
+rte_mlx4_pmd_init(void)
 {
-       (void)name;
-       (void)args;
-
        RTE_BUILD_BUG_ON(sizeof(wr_id_t) != sizeof(uint64_t));
        /*
         * RDMAV_HUGEPAGES_SAFE tells ibv_fork_init() we intend to use
@@ -5938,13 +5957,7 @@ rte_mlx4_pmd_init(const char *name, const char *args)
        setenv("RDMAV_HUGEPAGES_SAFE", "1", 1);
        ibv_fork_init();
        rte_eal_pci_register(&mlx4_driver.pci_drv);
-       return 0;
 }
 
-static struct rte_driver rte_mlx4_driver = {
-       .type = PMD_PDEV,
-       .init = rte_mlx4_pmd_init,
-};
-
-PMD_REGISTER_DRIVER(rte_mlx4_driver, mlx4);
-DRIVER_REGISTER_PCI_TABLE(mlx4, mlx4_pci_id_map);
+RTE_PMD_EXPORT_NAME(net_mlx4, __COUNTER__);
+RTE_PMD_REGISTER_PCI_TABLE(net_mlx4, mlx4_pci_id_map);