net/ixgbe: fix flow control mode setting
authorGuinan Sun <guinanx.sun@intel.com>
Tue, 18 Feb 2020 03:39:31 +0000 (03:39 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Wed, 19 Feb 2020 12:51:06 +0000 (13:51 +0100)
When the port restarts, the flow ctrl register will be reset,
we need to make sure it can be configured the same as previous setting,
otherwise a register read error would occur. This patch fixes this
issue.

Fixes: af75078fece3 ("first public release")
Cc: stable@dpdk.org
Signed-off-by: Guinan Sun <guinanx.sun@intel.com>
Tested-by: Tomasz Konieczny <tomaszx.konieczny@intel.com>
Reviewed-by: Xiaolong Ye <xiaolong.ye@intel.com>
drivers/net/ixgbe/ixgbe_ethdev.c
drivers/net/ixgbe/ixgbe_ethdev.h

index 0ef84a2..23b3f5b 100644 (file)
@@ -1176,8 +1176,8 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
        memset(dcb_config, 0, sizeof(struct ixgbe_dcb_config));
        ixgbe_dcb_init(hw, dcb_config);
        /* Get Hardware Flow Control setting */
-       hw->fc.requested_mode = ixgbe_fc_full;
-       hw->fc.current_mode = ixgbe_fc_full;
+       hw->fc.requested_mode = ixgbe_fc_none;
+       hw->fc.current_mode = ixgbe_fc_none;
        hw->fc.pause_time = IXGBE_FC_PAUSE;
        for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
                hw->fc.low_water[i] = IXGBE_FC_LO;
@@ -2538,6 +2538,39 @@ ixgbe_set_vf_rate_limit(struct rte_eth_dev *dev, uint16_t vf,
        return 0;
 }
 
+static int
+ixgbe_flow_ctrl_enable(struct rte_eth_dev *dev, struct ixgbe_hw *hw)
+{
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
+       int err;
+       uint32_t mflcn;
+
+       err = ixgbe_fc_enable(hw);
+
+       /* Not negotiated is not an error case */
+       if (err == IXGBE_SUCCESS || err == IXGBE_ERR_FC_NOT_NEGOTIATED) {
+               /*
+                *check if we want to forward MAC frames - driver doesn't
+                *have native capability to do that,
+                *so we'll write the registers ourselves
+                */
+
+               mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+
+               /* set or clear MFLCN.PMCF bit depending on configuration */
+               if (adapter->mac_ctrl_frame_fwd != 0)
+                       mflcn |= IXGBE_MFLCN_PMCF;
+               else
+                       mflcn &= ~IXGBE_MFLCN_PMCF;
+
+               IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn);
+               IXGBE_WRITE_FLUSH(hw);
+
+               return 0;
+       }
+       return err;
+}
+
 /*
  * Configure device link speed and setup link.
  * It returns 0 on success.
@@ -2664,6 +2697,12 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 
        ixgbe_restore_statistics_mapping(dev);
 
+       err = ixgbe_flow_ctrl_enable(dev, hw);
+       if (err < 0) {
+               PMD_INIT_LOG(ERR, "enable flow ctrl err");
+               goto error;
+       }
+
        err = ixgbe_dev_rxtx_start(dev);
        if (err < 0) {
                PMD_INIT_LOG(ERR, "Unable to start rxtx queues");
@@ -2900,6 +2939,8 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
 
        adapter->rss_reta_updated = 0;
 
+       adapter->mac_ctrl_frame_fwd = 0;
+
        hw->adapter_stopped = true;
 }
 
@@ -4718,10 +4759,10 @@ static int
 ixgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 {
        struct ixgbe_hw *hw;
+       struct ixgbe_adapter *adapter = dev->data->dev_private;
        int err;
        uint32_t rx_buf_size;
        uint32_t max_high_water;
-       uint32_t mflcn;
        enum ixgbe_fc_mode rte_fcmode_2_ixgbe_fcmode[] = {
                ixgbe_fc_none,
                ixgbe_fc_rx_pause,
@@ -4754,31 +4795,14 @@ ixgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
        hw->fc.low_water[0]   = fc_conf->low_water;
        hw->fc.send_xon       = fc_conf->send_xon;
        hw->fc.disable_fc_autoneg = !fc_conf->autoneg;
+       adapter->mac_ctrl_frame_fwd = fc_conf->mac_ctrl_frame_fwd;
 
-       err = ixgbe_fc_enable(hw);
-
-       /* Not negotiated is not an error case */
-       if ((err == IXGBE_SUCCESS) || (err == IXGBE_ERR_FC_NOT_NEGOTIATED)) {
-
-               /* check if we want to forward MAC frames - driver doesn't have native
-                * capability to do that, so we'll write the registers ourselves */
-
-               mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
-
-               /* set or clear MFLCN.PMCF bit depending on configuration */
-               if (fc_conf->mac_ctrl_frame_fwd != 0)
-                       mflcn |= IXGBE_MFLCN_PMCF;
-               else
-                       mflcn &= ~IXGBE_MFLCN_PMCF;
-
-               IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn);
-               IXGBE_WRITE_FLUSH(hw);
-
-               return 0;
+       err = ixgbe_flow_ctrl_enable(dev, hw);
+       if (err < 0) {
+               PMD_INIT_LOG(ERR, "ixgbe_flow_ctrl_enable = 0x%x", err);
+               return -EIO;
        }
-
-       PMD_INIT_LOG(ERR, "ixgbe_fc_enable = 0x%x", err);
-       return -EIO;
+       return err;
 }
 
 /**
index 5089347..b8df756 100644 (file)
@@ -511,6 +511,7 @@ struct ixgbe_adapter {
         * mailbox status) link status.
         */
        uint8_t pflink_fullchk;
+       uint8_t mac_ctrl_frame_fwd;
        rte_atomic32_t link_thread_running;
        pthread_t link_thread_tid;
 };