1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2024 ZTE Corporation 3 */ 4 5 #include <stdint.h> 6 #include <rte_malloc.h> 7 #include <rte_mbuf.h> 8 9 #include "zxdh_queue.h" 10 #include "zxdh_logs.h" 11 #include "zxdh_pci.h" 12 #include "zxdh_common.h" 13 #include "zxdh_msg.h" 14 15 struct rte_mbuf * 16 zxdh_virtqueue_detach_unused(struct zxdh_virtqueue *vq) 17 { 18 struct rte_mbuf *cookie = NULL; 19 int32_t idx = 0; 20 21 if (vq == NULL) 22 return NULL; 23 24 for (idx = 0; idx < vq->vq_nentries; idx++) { 25 cookie = vq->vq_descx[idx].cookie; 26 if (cookie != NULL) { 27 vq->vq_descx[idx].cookie = NULL; 28 return cookie; 29 } 30 } 31 return NULL; 32 } 33 34 static int32_t 35 zxdh_release_channel(struct rte_eth_dev *dev) 36 { 37 struct zxdh_hw *hw = dev->data->dev_private; 38 uint16_t nr_vq = hw->queue_num; 39 uint32_t var = 0; 40 uint32_t addr = 0; 41 uint32_t widx = 0; 42 uint32_t bidx = 0; 43 uint16_t pch = 0; 44 uint16_t lch = 0; 45 int32_t ret = 0; 46 47 ret = zxdh_timedlock(hw, 1000); 48 if (ret) { 49 PMD_DRV_LOG(ERR, "Acquiring hw lock got failed, timeout"); 50 return -1; 51 } 52 53 for (lch = 0; lch < nr_vq; lch++) { 54 if (hw->channel_context[lch].valid == 0) { 55 PMD_DRV_LOG(DEBUG, "Logic channel %d does not need to release", lch); 56 continue; 57 } 58 59 pch = hw->channel_context[lch].ph_chno; 60 widx = pch / 32; 61 bidx = pch % 32; 62 63 addr = ZXDH_QUERES_SHARE_BASE + (widx * sizeof(uint32_t)); 64 var = zxdh_read_bar_reg(dev, ZXDH_BAR0_INDEX, addr); 65 var &= ~(1 << bidx); 66 zxdh_write_bar_reg(dev, ZXDH_BAR0_INDEX, addr, var); 67 68 hw->channel_context[lch].valid = 0; 69 hw->channel_context[lch].ph_chno = 0; 70 } 71 72 zxdh_release_lock(hw); 73 74 return 0; 75 } 76 77 int32_t 78 zxdh_get_queue_type(uint16_t vtpci_queue_idx) 79 { 80 if (vtpci_queue_idx % 2 == 0) 81 return ZXDH_VTNET_RQ; 82 else 83 return ZXDH_VTNET_TQ; 84 } 85 86 int32_t 87 zxdh_free_queues(struct rte_eth_dev *dev) 88 { 89 struct zxdh_hw *hw = dev->data->dev_private; 90 uint16_t nr_vq = hw->queue_num; 91 struct zxdh_virtqueue *vq = NULL; 92 int32_t queue_type = 0; 93 uint16_t i = 0; 94 95 if (hw->vqs == NULL) 96 return 0; 97 98 if (zxdh_release_channel(dev) < 0) { 99 PMD_DRV_LOG(ERR, "Failed to clear coi table"); 100 return -1; 101 } 102 103 for (i = 0; i < nr_vq; i++) { 104 vq = hw->vqs[i]; 105 if (vq == NULL) 106 continue; 107 108 ZXDH_VTPCI_OPS(hw)->del_queue(hw, vq); 109 queue_type = zxdh_get_queue_type(i); 110 if (queue_type == ZXDH_VTNET_RQ) { 111 rte_free(vq->sw_ring); 112 rte_memzone_free(vq->rxq.mz); 113 } else if (queue_type == ZXDH_VTNET_TQ) { 114 rte_memzone_free(vq->txq.mz); 115 rte_memzone_free(vq->txq.zxdh_net_hdr_mz); 116 } 117 118 rte_free(vq); 119 hw->vqs[i] = NULL; 120 PMD_DRV_LOG(DEBUG, "Release to queue %d success!", i); 121 } 122 123 rte_free(hw->vqs); 124 hw->vqs = NULL; 125 126 return 0; 127 } 128