net/virtio: improve queue init error path
[dpdk.git] / drivers / net / e1000 / igb_ethdev.c
index 647aa8d..17ee6e9 100644 (file)
@@ -17,8 +17,8 @@
 #include <rte_pci.h>
 #include <rte_bus_pci.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_memory.h>
 #include <rte_eal.h>
 #include <rte_malloc.h>
@@ -194,10 +194,8 @@ static int igb_add_5tuple_filter_82576(struct rte_eth_dev *dev,
                        struct rte_eth_ntuple_filter *ntuple_filter);
 static int igb_remove_5tuple_filter_82576(struct rte_eth_dev *dev,
                        struct rte_eth_ntuple_filter *ntuple_filter);
-static int eth_igb_filter_ctrl(struct rte_eth_dev *dev,
-                    enum rte_filter_type filter_type,
-                    enum rte_filter_op filter_op,
-                    void *arg);
+static int eth_igb_flow_ops_get(struct rte_eth_dev *dev,
+                               const struct rte_flow_ops **ops);
 static int eth_igb_get_reg_length(struct rte_eth_dev *dev);
 static int eth_igb_get_regs(struct rte_eth_dev *dev,
                struct rte_dev_reg_info *regs);
@@ -374,7 +372,7 @@ static const struct eth_dev_ops eth_igb_ops = {
        .reta_query           = eth_igb_rss_reta_query,
        .rss_hash_update      = eth_igb_rss_hash_update,
        .rss_hash_conf_get    = eth_igb_rss_hash_conf_get,
-       .filter_ctrl          = eth_igb_filter_ctrl,
+       .flow_ops_get         = eth_igb_flow_ops_get,
        .set_mc_addr_list     = eth_igb_set_mc_addr_list,
        .rxq_info_get         = igb_rxq_info_get,
        .txq_info_get         = igb_txq_info_get,
@@ -3064,6 +3062,7 @@ eth_igb_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
        uint32_t rx_buf_size;
        uint32_t max_high_water;
        uint32_t rctl;
+       uint32_t ctrl;
 
        hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        if (fc_conf->autoneg != hw->mac.autoneg)
@@ -3101,6 +3100,39 @@ eth_igb_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
                        rctl &= ~E1000_RCTL_PMCF;
 
                E1000_WRITE_REG(hw, E1000_RCTL, rctl);
+
+               /*
+                * check if we want to change flow control mode - driver doesn't have native
+                * capability to do that, so we'll write the registers ourselves
+                */
+               ctrl = E1000_READ_REG(hw, E1000_CTRL);
+
+               /*
+                * set or clear E1000_CTRL_RFCE and E1000_CTRL_TFCE bits depending
+                * on configuration
+                */
+               switch (fc_conf->mode) {
+               case RTE_FC_NONE:
+                       ctrl &= ~E1000_CTRL_RFCE & ~E1000_CTRL_TFCE;
+                       break;
+               case RTE_FC_RX_PAUSE:
+                       ctrl |= E1000_CTRL_RFCE;
+                       ctrl &= ~E1000_CTRL_TFCE;
+                       break;
+               case RTE_FC_TX_PAUSE:
+                       ctrl |= E1000_CTRL_TFCE;
+                       ctrl &= ~E1000_CTRL_RFCE;
+                       break;
+               case RTE_FC_FULL:
+                       ctrl |= E1000_CTRL_RFCE | E1000_CTRL_TFCE;
+                       break;
+               default:
+                       PMD_INIT_LOG(ERR, "invalid flow control mode");
+                       return -EINVAL;
+               }
+
+               E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
+
                E1000_WRITE_FLUSH(hw);
 
                return 0;
@@ -4360,16 +4392,20 @@ eth_igb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
                        frame_size > dev_info.max_rx_pktlen)
                return -EINVAL;
 
-       /* refuse mtu that requires the support of scattered packets when this
-        * feature has not been enabled before. */
-       if (!dev->data->scattered_rx &&
-           frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM)
+       /*
+        * If device is started, refuse mtu that requires the support of
+        * scattered packets when this feature has not been enabled before.
+        */
+       if (dev->data->dev_started && !dev->data->scattered_rx &&
+           frame_size > dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM) {
+               PMD_INIT_LOG(ERR, "Stop port first.");
                return -EINVAL;
+       }
 
        rctl = E1000_READ_REG(hw, E1000_RCTL);
 
        /* switch to jumbo mode if needed */
-       if (frame_size > RTE_ETHER_MAX_LEN) {
+       if (frame_size > E1000_ETH_MAX_LEN) {
                dev->data->dev_conf.rxmode.offloads |=
                        DEV_RX_OFFLOAD_JUMBO_FRAME;
                rctl |= E1000_RCTL_LPE;
@@ -4545,26 +4581,11 @@ igb_add_del_ethertype_filter(struct rte_eth_dev *dev,
 }
 
 static int
-eth_igb_filter_ctrl(struct rte_eth_dev *dev __rte_unused,
-                    enum rte_filter_type filter_type,
-                    enum rte_filter_op filter_op,
-                    void *arg)
+eth_igb_flow_ops_get(struct rte_eth_dev *dev __rte_unused,
+                    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 = &igb_flow_ops;
-               break;
-       default:
-               PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
-                                                       filter_type);
-               break;
-       }
-
-       return ret;
+       *ops = &igb_flow_ops;
+       return 0;
 }
 
 static int