#include "hnae3.h"
 #include "hns3_enet.h"
 
+static void hns3_clear_all_ring(struct hnae3_handle *h);
+static void hns3_force_clear_all_rx_ring(struct hnae3_handle *h);
+
 static const char hns3_driver_name[] = "hns3";
 const char hns3_driver_version[] = VERMAGIC_STRING;
 static const char hns3_driver_string[] =
        int i, j;
        int ret;
 
+       ret = hns3_nic_reset_all_ring(h);
+       if (ret)
+               return ret;
+
        /* get irq resource for all vectors */
        ret = hns3_nic_init_irq(priv);
        if (ret) {
        if (test_and_set_bit(HNS3_NIC_STATE_DOWN, &priv->state))
                return;
 
+       /* disable vectors */
+       for (i = 0; i < priv->vector_num; i++)
+               hns3_vector_disable(&priv->tqp_vector[i]);
+
        /* stop ae_dev */
        ops = priv->ae_handle->ae_algo->ops;
        if (ops->stop)
                ops->stop(priv->ae_handle);
 
-       /* disable vectors */
-       for (i = 0; i < priv->vector_num; i++)
-               hns3_vector_disable(&priv->tqp_vector[i]);
-
        /* free irq resources */
        hns3_nic_uninit_irq(priv);
+
+       hns3_clear_all_ring(priv->ae_handle);
 }
 
 static int hns3_nic_net_stop(struct net_device *netdev)
                        goto out_when_alloc_ring_memory;
                }
 
-               hns3_init_ring_hw(priv->ring_data[i].ring);
-
                u64_stats_init(&priv->ring_data[i].ring->syncp);
        }
 
        if (netdev->reg_state != NETREG_UNINITIALIZED)
                unregister_netdev(netdev);
 
+       hns3_force_clear_all_rx_ring(handle);
+
        ret = hns3_nic_uninit_vector_data(priv);
        if (ret)
                netdev_err(netdev, "uninit vector error\n");
 static void hns3_clear_tx_ring(struct hns3_enet_ring *ring)
 {
        while (ring->next_to_clean != ring->next_to_use) {
+               ring->desc[ring->next_to_clean].tx.bdtp_fe_sc_vld_ra_ri = 0;
                hns3_free_buffer_detach(ring, ring->next_to_clean);
                ring_ptr_move_fw(ring, next_to_clean);
        }
 }
 
-static void hns3_clear_rx_ring(struct hns3_enet_ring *ring)
+static int hns3_clear_rx_ring(struct hns3_enet_ring *ring)
+{
+       struct hns3_desc_cb res_cbs;
+       int ret;
+
+       while (ring->next_to_use != ring->next_to_clean) {
+               /* When a buffer is not reused, it's memory has been
+                * freed in hns3_handle_rx_bd or will be freed by
+                * stack, so we need to replace the buffer here.
+                */
+               if (!ring->desc_cb[ring->next_to_use].reuse_flag) {
+                       ret = hns3_reserve_buffer_map(ring, &res_cbs);
+                       if (ret) {
+                               u64_stats_update_begin(&ring->syncp);
+                               ring->stats.sw_err_cnt++;
+                               u64_stats_update_end(&ring->syncp);
+                               /* if alloc new buffer fail, exit directly
+                                * and reclear in up flow.
+                                */
+                               netdev_warn(ring->tqp->handle->kinfo.netdev,
+                                           "reserve buffer map failed, ret = %d\n",
+                                           ret);
+                               return ret;
+                       }
+                       hns3_replace_buffer(ring, ring->next_to_use,
+                                           &res_cbs);
+               }
+               ring_ptr_move_fw(ring, next_to_use);
+       }
+
+       return 0;
+}
+
+static void hns3_force_clear_rx_ring(struct hns3_enet_ring *ring)
 {
        while (ring->next_to_use != ring->next_to_clean) {
                /* When a buffer is not reused, it's memory has been
        }
 }
 
+static void hns3_force_clear_all_rx_ring(struct hnae3_handle *h)
+{
+       struct net_device *ndev = h->kinfo.netdev;
+       struct hns3_nic_priv *priv = netdev_priv(ndev);
+       struct hns3_enet_ring *ring;
+       u32 i;
+
+       for (i = 0; i < h->kinfo.num_tqps; i++) {
+               ring = priv->ring_data[i + h->kinfo.num_tqps].ring;
+               hns3_force_clear_rx_ring(ring);
+       }
+}
+
 static void hns3_clear_all_ring(struct hnae3_handle *h)
 {
        struct net_device *ndev = h->kinfo.netdev;
                netdev_tx_reset_queue(dev_queue);
 
                ring = priv->ring_data[i + h->kinfo.num_tqps].ring;
+               /* Continue to clear other rings even if clearing some
+                * rings failed.
+                */
                hns3_clear_rx_ring(ring);
        }
 }
 
+int hns3_nic_reset_all_ring(struct hnae3_handle *h)
+{
+       struct net_device *ndev = h->kinfo.netdev;
+       struct hns3_nic_priv *priv = netdev_priv(ndev);
+       struct hns3_enet_ring *rx_ring;
+       int i, j;
+       int ret;
+
+       for (i = 0; i < h->kinfo.num_tqps; i++) {
+               h->ae_algo->ops->reset_queue(h, i);
+               hns3_init_ring_hw(priv->ring_data[i].ring);
+
+               /* We need to clear tx ring here because self test will
+                * use the ring and will not run down before up
+                */
+               hns3_clear_tx_ring(priv->ring_data[i].ring);
+               priv->ring_data[i].ring->next_to_clean = 0;
+               priv->ring_data[i].ring->next_to_use = 0;
+
+               rx_ring = priv->ring_data[i + h->kinfo.num_tqps].ring;
+               hns3_init_ring_hw(rx_ring);
+               ret = hns3_clear_rx_ring(rx_ring);
+               if (ret)
+                       return ret;
+
+               /* We can not know the hardware head and tail when this
+                * function is called in reset flow, so we reuse all desc.
+                */
+               for (j = 0; j < rx_ring->desc_num; j++)
+                       hns3_reuse_buffer(rx_ring, j);
+
+               rx_ring->next_to_clean = 0;
+               rx_ring->next_to_use = 0;
+       }
+
+       return 0;
+}
+
 static int hns3_reset_notify_down_enet(struct hnae3_handle *handle)
 {
        struct hnae3_knic_private_info *kinfo = &handle->kinfo;
        struct hns3_nic_priv *priv = netdev_priv(netdev);
        int ret;
 
-       hns3_clear_all_ring(handle);
+       hns3_force_clear_all_rx_ring(handle);
 
        ret = hns3_nic_uninit_vector_data(priv);
        if (ret) {
        if (if_running)
                hns3_nic_net_stop(netdev);
 
-       hns3_clear_all_ring(h);
-
        ret = hns3_nic_uninit_vector_data(priv);
        if (ret) {
                dev_err(&netdev->dev,