net/ixgbe: fix MAC resource leak
[dpdk.git] / drivers / net / ixgbe / ixgbe_ethdev.c
index d7a1806..47693c0 100644 (file)
@@ -27,8 +27,8 @@
 #include <rte_eal.h>
 #include <rte_alarm.h>
 #include <rte_ether.h>
-#include <rte_ethdev_driver.h>
-#include <rte_ethdev_pci.h>
+#include <ethdev_driver.h>
+#include <ethdev_pci.h>
 #include <rte_malloc.h>
 #include <rte_random.h>
 #include <rte_dev.h>
@@ -304,10 +304,8 @@ static int ixgbe_add_5tuple_filter(struct rte_eth_dev *dev,
                        struct ixgbe_5tuple_filter *filter);
 static void ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev,
                        struct ixgbe_5tuple_filter *filter);
-static int ixgbe_dev_filter_ctrl(struct rte_eth_dev *dev,
-                    enum rte_filter_type filter_type,
-                    enum rte_filter_op filter_op,
-                    void *arg);
+static int ixgbe_dev_flow_ops_get(struct rte_eth_dev *dev,
+                                 const struct rte_flow_ops **ops);
 static int ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
 
 static int ixgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
@@ -538,7 +536,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
        .reta_query           = ixgbe_dev_rss_reta_query,
        .rss_hash_update      = ixgbe_dev_rss_hash_update,
        .rss_hash_conf_get    = ixgbe_dev_rss_hash_conf_get,
-       .filter_ctrl          = ixgbe_dev_filter_ctrl,
+       .flow_ops_get         = ixgbe_dev_flow_ops_get,
        .set_mc_addr_list     = ixgbe_dev_set_mc_addr_list,
        .rxq_info_get         = ixgbe_rxq_info_get,
        .txq_info_get         = ixgbe_txq_info_get,
@@ -560,6 +558,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
        .udp_tunnel_port_del  = ixgbe_dev_udp_tunnel_port_del,
        .tm_ops_get           = ixgbe_tm_ops_get,
        .tx_done_cleanup      = ixgbe_dev_tx_done_cleanup,
+       .get_monitor_addr     = ixgbe_get_monitor_addr,
 };
 
 /*
@@ -606,6 +605,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
        .rss_hash_update      = ixgbe_dev_rss_hash_update,
        .rss_hash_conf_get    = ixgbe_dev_rss_hash_conf_get,
        .tx_done_cleanup      = ixgbe_dev_tx_done_cleanup,
+       .get_monitor_addr     = ixgbe_get_monitor_addr,
 };
 
 /* store statistics names and its offset in stats structure */
@@ -1218,6 +1218,8 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
                PMD_INIT_LOG(ERR,
                             "Failed to allocate %d bytes needed to store MAC addresses",
                             RTE_ETHER_ADDR_LEN * IXGBE_VMDQ_NUM_UC_MAC);
+               rte_free(eth_dev->data->mac_addrs);
+               eth_dev->data->mac_addrs = NULL;
                return -ENOMEM;
        }
 
@@ -1393,6 +1395,7 @@ static int ixgbe_fdir_filter_init(struct rte_eth_dev *eth_dev)
        if (!fdir_info->hash_map) {
                PMD_INIT_LOG(ERR,
                             "Failed to allocate memory for fdir hash map!");
+               rte_hash_free(fdir_info->hash_handle);
                return -ENOMEM;
        }
        fdir_info->mask_added = FALSE;
@@ -1429,6 +1432,7 @@ static int ixgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev)
        if (!l2_tn_info->hash_map) {
                PMD_INIT_LOG(ERR,
                        "Failed to allocate memory for L2 TN hash map!");
+               rte_hash_free(l2_tn_info->hash_handle);
                return -ENOMEM;
        }
        l2_tn_info->e_tag_en = FALSE;
@@ -1650,13 +1654,8 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
                }
                PMD_INIT_LOG(INFO, "\tVF MAC address not assigned by Host PF");
                PMD_INIT_LOG(INFO, "\tAssign randomly generated MAC address "
-                            "%02x:%02x:%02x:%02x:%02x:%02x",
-                            perm_addr->addr_bytes[0],
-                            perm_addr->addr_bytes[1],
-                            perm_addr->addr_bytes[2],
-                            perm_addr->addr_bytes[3],
-                            perm_addr->addr_bytes[4],
-                            perm_addr->addr_bytes[5]);
+                            RTE_ETHER_ADDR_PRT_FMT,
+                                RTE_ETHER_ADDR_BYTES(perm_addr));
        }
 
        /* Copy the permanent MAC address */
@@ -1670,6 +1669,8 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
 
        default:
                PMD_INIT_LOG(ERR, "VF Initialization Failure: %d", diag);
+               rte_free(eth_dev->data->mac_addrs);
+               eth_dev->data->mac_addrs = NULL;
                return -EIO;
        }
 
@@ -1717,6 +1718,13 @@ eth_ixgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
        } else
                memset(&eth_da, 0, sizeof(eth_da));
 
+       if (eth_da.nb_representor_ports > 0 &&
+           eth_da.type != RTE_ETH_REPRESENTOR_VF) {
+               PMD_DRV_LOG(ERR, "unsupported representor type: %s\n",
+                           pci_dev->device.devargs->args);
+               return -ENOTSUP;
+       }
+
        retval = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name,
                sizeof(struct ixgbe_adapter),
                eth_dev_pci_specific_init, pci_dev,
@@ -3338,6 +3346,13 @@ ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
                          hw_stats->fccrc +
                          hw_stats->fclast;
 
+       /*
+        * 82599 errata, UDP frames with a 0 checksum can be marked as checksum
+        * errors.
+        */
+       if (hw->mac.type != ixgbe_mac_82599EB)
+               stats->ierrors += hw_stats->xec;
+
        /* Tx Errors */
        stats->oerrors  = 0;
        return 0;
@@ -3784,6 +3799,7 @@ ixgbevf_dev_stats_reset(struct rte_eth_dev *dev)
        hw_stats->vfgorc = 0;
        hw_stats->vfgptc = 0;
        hw_stats->vfgotc = 0;
+       hw_stats->vfmprc = 0;
 
        return 0;
 }
@@ -3801,9 +3817,11 @@ ixgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
 
        etrack_id = (eeprom_verh << 16) | eeprom_verl;
        ret = snprintf(fw_version, fw_size, "0x%08x", etrack_id);
+       if (ret < 0)
+               return -EINVAL;
 
        ret += 1; /* add the size of '\0' */
-       if (fw_size < (u32)ret)
+       if (fw_size < (size_t)ret)
                return ret;
        else
                return 0;
@@ -5007,11 +5025,19 @@ ixgbe_dev_rss_reta_update(struct rte_eth_dev *dev,
        uint32_t reta, r;
        uint16_t idx, shift;
        struct ixgbe_adapter *adapter = dev->data->dev_private;
+       struct rte_eth_dev_data *dev_data = dev->data;
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        uint32_t reta_reg;
 
        PMD_INIT_FUNC_TRACE();
 
+       if (!dev_data->dev_started) {
+               PMD_DRV_LOG(ERR,
+                       "port %d must be started before rss reta update",
+                        dev_data->port_id);
+               return -EIO;
+       }
+
        if (!ixgbe_rss_update_sp(hw->mac.type)) {
                PMD_DRV_LOG(ERR, "RSS reta update is not supported on this "
                        "NIC.");
@@ -5173,7 +5199,7 @@ ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
        hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
 
        /* switch to jumbo mode if needed */
-       if (frame_size > RTE_ETHER_MAX_LEN) {
+       if (frame_size > IXGBE_ETH_MAX_LEN) {
                dev->data->dev_conf.rxmode.offloads |=
                        DEV_RX_OFFLOAD_JUMBO_FRAME;
                hlreg0 |= IXGBE_HLREG0_JUMBOEN;
@@ -5340,8 +5366,10 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)
                 * now only one vector is used for Rx queue
                 */
                intr_vector = 1;
-               if (rte_intr_efd_enable(intr_handle, intr_vector))
+               if (rte_intr_efd_enable(intr_handle, intr_vector)) {
+                       ixgbe_dev_clear_queues(dev);
                        return -1;
+               }
        }
 
        if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) {
@@ -5351,6 +5379,7 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)
                if (intr_handle->intr_vec == NULL) {
                        PMD_INIT_LOG(ERR, "Failed to allocate %d rx_queues"
                                     " intr_vec", dev->data->nb_rx_queues);
+                       ixgbe_dev_clear_queues(dev);
                        return -ENOMEM;
                }
        }
@@ -6277,14 +6306,8 @@ ixgbevf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
        diag = ixgbevf_set_uc_addr_vf(hw, 2, mac_addr->addr_bytes);
        if (diag != 0)
                PMD_DRV_LOG(ERR, "Unable to add MAC address "
-                           "%02x:%02x:%02x:%02x:%02x:%02x - diag=%d",
-                           mac_addr->addr_bytes[0],
-                           mac_addr->addr_bytes[1],
-                           mac_addr->addr_bytes[2],
-                           mac_addr->addr_bytes[3],
-                           mac_addr->addr_bytes[4],
-                           mac_addr->addr_bytes[5],
-                           diag);
+                           RTE_ETHER_ADDR_PRT_FMT " - diag=%d",
+                           RTE_ETHER_ADDR_BYTES(mac_addr), diag);
        return diag;
 }
 
@@ -6326,14 +6349,8 @@ ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index)
                if (diag != 0)
                        PMD_DRV_LOG(ERR,
                                    "Adding again MAC address "
-                                   "%02x:%02x:%02x:%02x:%02x:%02x failed "
-                                   "diag=%d",
-                                   mac_addr->addr_bytes[0],
-                                   mac_addr->addr_bytes[1],
-                                   mac_addr->addr_bytes[2],
-                                   mac_addr->addr_bytes[3],
-                                   mac_addr->addr_bytes[4],
-                                   mac_addr->addr_bytes[5],
+                                    RTE_ETHER_ADDR_PRT_FMT " failed "
+                                   "diag=%d", RTE_ETHER_ADDR_BYTES(mac_addr),
                                    diag);
        }
 }
@@ -6797,27 +6814,11 @@ ixgbe_add_del_ethertype_filter(struct rte_eth_dev *dev,
 }
 
 static int
-ixgbe_dev_filter_ctrl(__rte_unused struct rte_eth_dev *dev,
-                    enum rte_filter_type filter_type,
-                    enum rte_filter_op filter_op,
-                    void *arg)
+ixgbe_dev_flow_ops_get(__rte_unused struct rte_eth_dev *dev,
+                      const struct rte_flow_ops **ops)
 {
-       int ret = 0;
-
-       switch (filter_type) {
-       case RTE_ETH_FILTER_GENERIC:
-               if (filter_op != RTE_ETH_FILTER_GET)
-                       return -EINVAL;
-               *(const void **)arg = &ixgbe_flow_ops;
-               break;
-       default:
-               PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
-                                                       filter_type);
-               ret = -EINVAL;
-               break;
-       }
-
-       return ret;
+       *ops = &ixgbe_flow_ops;
+       return 0;
 }
 
 static u8 *
@@ -7332,9 +7333,6 @@ ixgbe_get_module_eeprom(struct rte_eth_dev *dev,
        uint8_t *data = info->data;
        uint32_t i = 0;
 
-       if (info->length == 0)
-               return -EINVAL;
-
        for (i = info->offset; i < info->offset + info->length; i++) {
                if (i < RTE_ETH_MODULE_SFF_8079_LEN)
                        status = hw->phy.ops.read_i2c_eeprom(hw, i, &databyte);
@@ -8451,15 +8449,12 @@ RTE_PMD_REGISTER_KMOD_DEP(net_ixgbe_vf, "* igb_uio | vfio-pci");
 RTE_PMD_REGISTER_PARAM_STRING(net_ixgbe_vf,
                              IXGBEVF_DEVARG_PFLINK_FULLCHK "=<0|1>");
 
-RTE_LOG_REGISTER(ixgbe_logtype_init, pmd.net.ixgbe.init, NOTICE);
-RTE_LOG_REGISTER(ixgbe_logtype_driver, pmd.net.ixgbe.driver, NOTICE);
+RTE_LOG_REGISTER_SUFFIX(ixgbe_logtype_init, init, NOTICE);
+RTE_LOG_REGISTER_SUFFIX(ixgbe_logtype_driver, driver, NOTICE);
 
-#ifdef RTE_LIBRTE_IXGBE_DEBUG_RX
-RTE_LOG_REGISTER(ixgbe_logtype_rx, pmd.net.ixgbe.rx, DEBUG);
-#endif
-#ifdef RTE_LIBRTE_IXGBE_DEBUG_TX
-RTE_LOG_REGISTER(ixgbe_logtype_tx, pmd.net.ixgbe.tx, DEBUG);
+#ifdef RTE_ETHDEV_DEBUG_RX
+RTE_LOG_REGISTER_SUFFIX(ixgbe_logtype_rx, rx, DEBUG);
 #endif
-#ifdef RTE_LIBRTE_IXGBE_DEBUG_TX_FREE
-RTE_LOG_REGISTER(ixgbe_logtype_tx_free, pmd.net.ixgbe.tx_free, DEBUG);
+#ifdef RTE_ETHDEV_DEBUG_TX
+RTE_LOG_REGISTER_SUFFIX(ixgbe_logtype_tx, tx, DEBUG);
 #endif