]> git.droids-corp.org - dpdk.git/commitdiff
net/ice: workaround DCF reset failure
authorDapeng Yu <dapengx.yu@intel.com>
Tue, 26 Oct 2021 09:53:07 +0000 (17:53 +0800)
committerQi Zhang <qi.z.zhang@intel.com>
Wed, 27 Oct 2021 03:25:25 +0000 (05:25 +0200)
After DCF is reset by PF, the DCF device un-initialization cannot
function normally, ignore the failure does not help since the kernel
does not clean up resource.

The patch workaround the issue by triggering an additional DCF enable/
disable cycle when a passive reset is detected.

Fixes: 1a86f4dbdf42 ("net/ice: support DCF device reset")
Cc: stable@dpdk.org
Signed-off-by: Dapeng Yu <dapengx.yu@intel.com>
Acked-by: Qi Zhang <qi.z.zhang@intel.com>
drivers/net/ice/ice_dcf.c
drivers/net/ice/ice_dcf_ethdev.c

index 084f7a53dbbe90c4ee7d7a0557fc8d26ecb6d5c1..366ff0a9074b43ed6511d4a7abeafb011e1ed416 100644 (file)
@@ -593,6 +593,8 @@ ice_dcf_init_hw(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw)
        struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
        int ret, size;
 
+       hw->resetting = false;
+
        hw->avf.hw_addr = pci_dev->mem_resource[0].addr;
        hw->avf.back = hw;
 
index 7c71a48010b88f3ee91fa9a64b7661abd30b642f..4d9484e99478742a5c4ff3edc618d363a1083de0 100644 (file)
@@ -1025,11 +1025,44 @@ ice_dcf_tm_ops_get(struct rte_eth_dev *dev __rte_unused,
        return 0;
 }
 
+static inline void
+ice_dcf_reset_hw(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw)
+{
+       ice_dcf_uninit_hw(eth_dev, hw);
+       ice_dcf_init_hw(eth_dev, hw);
+}
+
+/* Check if reset has been triggered by PF */
+static inline bool
+ice_dcf_is_reset(struct rte_eth_dev *dev)
+{
+       struct ice_dcf_adapter *ad = dev->data->dev_private;
+       struct iavf_hw *hw = &ad->real_hw.avf;
+
+       return !(IAVF_READ_REG(hw, IAVF_VF_ARQLEN1) &
+                IAVF_VF_ARQLEN1_ARQENABLE_MASK);
+}
+
 static int
 ice_dcf_dev_reset(struct rte_eth_dev *dev)
 {
+       struct ice_dcf_adapter *ad = dev->data->dev_private;
+       struct ice_dcf_hw *hw = &ad->real_hw;
        int ret;
 
+       if (ice_dcf_is_reset(dev)) {
+               if (!ad->real_hw.resetting)
+                       ad->real_hw.resetting = true;
+               PMD_DRV_LOG(ERR, "The DCF has been reset by PF");
+
+               /*
+                * Simply reset hw to trigger an additional DCF enable/disable
+                * cycle which help to workaround the issue that kernel driver
+                * may not clean up resource during previous reset.
+                */
+               ice_dcf_reset_hw(dev, hw);
+       }
+
        ret = ice_dcf_dev_uninit(dev);
        if (ret)
                return ret;
@@ -1072,7 +1105,6 @@ ice_dcf_dev_init(struct rte_eth_dev *eth_dev)
 {
        struct ice_dcf_adapter *adapter = eth_dev->data->dev_private;
 
-       adapter->real_hw.resetting = false;
        eth_dev->dev_ops = &ice_dcf_eth_dev_ops;
        eth_dev->rx_pkt_burst = ice_dcf_recv_pkts;
        eth_dev->tx_pkt_burst = ice_dcf_xmit_pkts;