Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2024 ZTE Corporation
3 : : */
4 : :
5 : : #include <ethdev_pci.h>
6 : : #include <bus_pci_driver.h>
7 : : #include <rte_ethdev.h>
8 : : #include <rte_malloc.h>
9 : : #include <rte_io.h>
10 : :
11 : : #include "zxdh_ethdev.h"
12 : : #include "zxdh_logs.h"
13 : : #include "zxdh_pci.h"
14 : : #include "zxdh_msg.h"
15 : : #include "zxdh_common.h"
16 : : #include "zxdh_queue.h"
17 : : #include "zxdh_np.h"
18 : : #include "zxdh_tables.h"
19 : : #include "zxdh_rxtx.h"
20 : : #include "zxdh_ethdev_ops.h"
21 : :
22 : : struct zxdh_hw_internal zxdh_hw_internal[RTE_MAX_ETHPORTS];
23 : : struct zxdh_dev_nic_shared_data dev_nic_sd[ZXDH_SLOT_MAX];
24 : : static rte_spinlock_t zxdh_shared_data_lock = RTE_SPINLOCK_INITIALIZER;
25 : : struct zxdh_shared_data *zxdh_shared_data;
26 : : struct zxdh_mtr_res g_mtr_res;
27 : :
28 : : #define ZXDH_INVALID_DTBQUE 0xFFFF
29 : : #define ZXDH_INVALID_SLOT_IDX 0xFFFF
30 : : #define ZXDH_PF_QUEUE_PAIRS_ADDR 0x5742
31 : : #define ZXDH_VF_QUEUE_PAIRS_ADDR 0x5744
32 : : #define ZXDH_QUEUE_POOL_ADDR 0x56A0
33 : :
34 : : uint16_t
35 : 0 : zxdh_vport_to_vfid(union zxdh_virport_num v)
36 : : {
37 : : /* epid > 4 is local soft queue. return 1192 */
38 [ # # ]: 0 : if (v.epid > 4)
39 : : return 1192;
40 [ # # ]: 0 : if (v.vf_flag)
41 : 0 : return v.epid * 256 + v.vfid;
42 : : else
43 : 0 : return (v.epid * 8 + v.pfid) + 1152;
44 : : }
45 : :
46 : : static int32_t
47 : 0 : zxdh_dev_infos_get(struct rte_eth_dev *dev,
48 : : struct rte_eth_dev_info *dev_info)
49 : : {
50 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
51 : :
52 : 0 : dev_info->speed_capa = rte_eth_speed_bitflag(hw->speed, RTE_ETH_LINK_FULL_DUPLEX);
53 : 0 : dev_info->max_rx_queues = hw->max_queue_pairs;
54 : 0 : dev_info->max_tx_queues = hw->max_queue_pairs;
55 : 0 : dev_info->min_rx_bufsize = ZXDH_MIN_RX_BUFSIZE;
56 : 0 : dev_info->max_rx_pktlen = ZXDH_MAX_RX_PKTLEN;
57 : 0 : dev_info->max_mac_addrs = ZXDH_MAX_MAC_ADDRS;
58 : : dev_info->rx_offload_capa = (RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
59 : : RTE_ETH_RX_OFFLOAD_VLAN_FILTER |
60 : : RTE_ETH_RX_OFFLOAD_QINQ_STRIP);
61 : : dev_info->rx_offload_capa |= (RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
62 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
63 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
64 : : RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
65 : : RTE_ETH_RX_OFFLOAD_OUTER_UDP_CKSUM);
66 : : dev_info->rx_offload_capa |= (RTE_ETH_RX_OFFLOAD_SCATTER);
67 : : dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TCP_LRO;
68 : 0 : dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
69 : :
70 : 0 : dev_info->reta_size = RTE_ETH_RSS_RETA_SIZE_256;
71 : 0 : dev_info->flow_type_rss_offloads = ZXDH_RSS_HF;
72 : :
73 : 0 : dev_info->max_mtu = ZXDH_MAX_RX_PKTLEN - RTE_ETHER_HDR_LEN -
74 : : RTE_VLAN_HLEN - ZXDH_DL_NET_HDR_SIZE;
75 : 0 : dev_info->min_mtu = ZXDH_ETHER_MIN_MTU;
76 : :
77 : : dev_info->tx_offload_capa = (RTE_ETH_TX_OFFLOAD_MULTI_SEGS);
78 : : dev_info->tx_offload_capa |= (RTE_ETH_TX_OFFLOAD_TCP_TSO |
79 : : RTE_ETH_TX_OFFLOAD_UDP_TSO |
80 : : RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO);
81 : : dev_info->tx_offload_capa |= (RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
82 : : RTE_ETH_TX_OFFLOAD_QINQ_INSERT |
83 : : RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO);
84 : 0 : dev_info->tx_offload_capa |= (RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
85 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
86 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
87 : : RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM);
88 : :
89 : 0 : return 0;
90 : : }
91 : :
92 : : static void
93 : 0 : zxdh_queues_unbind_intr(struct rte_eth_dev *dev)
94 : : {
95 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
96 : : int32_t i;
97 : :
98 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; ++i)
99 : 0 : ZXDH_VTPCI_OPS(hw)->set_queue_irq(hw, hw->vqs[i * 2], ZXDH_MSI_NO_VECTOR);
100 : :
101 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; ++i)
102 : 0 : ZXDH_VTPCI_OPS(hw)->set_queue_irq(hw, hw->vqs[i * 2 + 1], ZXDH_MSI_NO_VECTOR);
103 : 0 : }
104 : :
105 : :
106 : : static int32_t
107 : 0 : zxdh_intr_unmask(struct rte_eth_dev *dev)
108 : : {
109 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
110 : :
111 [ # # ]: 0 : if (rte_intr_ack(dev->intr_handle) < 0)
112 : : return -1;
113 : :
114 : 0 : hw->use_msix = zxdh_pci_msix_detect(RTE_ETH_DEV_TO_PCI(dev));
115 : :
116 : 0 : return 0;
117 : : }
118 : :
119 : : static void
120 : 0 : zxdh_devconf_intr_handler(void *param)
121 : : {
122 : : struct rte_eth_dev *dev = param;
123 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
124 : :
125 : 0 : uint8_t isr = zxdh_pci_isr(hw);
126 : :
127 [ # # ]: 0 : if (zxdh_intr_unmask(dev) < 0)
128 : 0 : PMD_DRV_LOG(ERR, "interrupt enable failed");
129 [ # # ]: 0 : if (isr & ZXDH_PCI_ISR_CONFIG) {
130 [ # # ]: 0 : if (zxdh_dev_link_update(dev, 0) == 0)
131 : 0 : rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
132 : : }
133 : 0 : }
134 : :
135 : :
136 : : /* Interrupt handler triggered by NIC for handling specific interrupt. */
137 : : static void
138 : 0 : zxdh_fromriscv_intr_handler(void *param)
139 : : {
140 : : struct rte_eth_dev *dev = param;
141 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
142 : 0 : uint64_t virt_addr = (uint64_t)(hw->bar_addr[ZXDH_BAR0_INDEX] + ZXDH_CTRLCH_OFFSET);
143 : :
144 [ # # ]: 0 : if (hw->is_pf) {
145 : 0 : PMD_DRV_LOG(DEBUG, "zxdh_risc2pf_intr_handler");
146 : 0 : zxdh_bar_irq_recv(ZXDH_MSG_CHAN_END_RISC, ZXDH_MSG_CHAN_END_PF, virt_addr, dev);
147 : : } else {
148 : 0 : PMD_DRV_LOG(DEBUG, "zxdh_riscvf_intr_handler");
149 : 0 : zxdh_bar_irq_recv(ZXDH_MSG_CHAN_END_RISC, ZXDH_MSG_CHAN_END_VF, virt_addr, dev);
150 : : }
151 : 0 : }
152 : :
153 : : /* Interrupt handler triggered by NIC for handling specific interrupt. */
154 : : static void
155 : 0 : zxdh_frompfvf_intr_handler(void *param)
156 : : {
157 : : struct rte_eth_dev *dev = param;
158 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
159 : 0 : uint64_t virt_addr = (uint64_t)(hw->bar_addr[ZXDH_BAR0_INDEX] +
160 : : ZXDH_MSG_CHAN_PFVFSHARE_OFFSET);
161 : :
162 [ # # ]: 0 : if (hw->is_pf) {
163 : 0 : PMD_DRV_LOG(DEBUG, "zxdh_vf2pf_intr_handler");
164 : 0 : zxdh_bar_irq_recv(ZXDH_MSG_CHAN_END_VF, ZXDH_MSG_CHAN_END_PF, virt_addr, dev);
165 : : } else {
166 : 0 : PMD_DRV_LOG(DEBUG, "zxdh_pf2vf_intr_handler");
167 : 0 : zxdh_bar_irq_recv(ZXDH_MSG_CHAN_END_PF, ZXDH_MSG_CHAN_END_VF, virt_addr, dev);
168 : : }
169 : 0 : }
170 : :
171 : : static void
172 : 0 : zxdh_intr_cb_reg(struct rte_eth_dev *dev)
173 : : {
174 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
175 : :
176 [ # # ]: 0 : if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
177 : 0 : rte_intr_callback_unregister(dev->intr_handle, zxdh_devconf_intr_handler, dev);
178 : :
179 : : /* register callback to update dev config intr */
180 : 0 : rte_intr_callback_register(dev->intr_handle, zxdh_devconf_intr_handler, dev);
181 : : /* Register rsic_v to pf interrupt callback */
182 : 0 : struct rte_intr_handle *tmp = hw->risc_intr +
183 : : (ZXDH_MSIX_FROM_PFVF - ZXDH_MSIX_INTR_MSG_VEC_BASE);
184 : :
185 : 0 : rte_intr_callback_register(tmp, zxdh_frompfvf_intr_handler, dev);
186 : :
187 : 0 : tmp = hw->risc_intr + (ZXDH_MSIX_FROM_RISCV - ZXDH_MSIX_INTR_MSG_VEC_BASE);
188 : 0 : rte_intr_callback_register(tmp, zxdh_fromriscv_intr_handler, dev);
189 : 0 : }
190 : :
191 : : static void
192 : 0 : zxdh_intr_cb_unreg(struct rte_eth_dev *dev)
193 : : {
194 [ # # ]: 0 : if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
195 : 0 : rte_intr_callback_unregister(dev->intr_handle, zxdh_devconf_intr_handler, dev);
196 : :
197 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
198 : :
199 : : /* register callback to update dev config intr */
200 : 0 : rte_intr_callback_unregister(dev->intr_handle, zxdh_devconf_intr_handler, dev);
201 : : /* Register rsic_v to pf interrupt callback */
202 : 0 : struct rte_intr_handle *tmp = hw->risc_intr +
203 : : (ZXDH_MSIX_FROM_PFVF - ZXDH_MSIX_INTR_MSG_VEC_BASE);
204 : :
205 : 0 : rte_intr_callback_unregister(tmp, zxdh_frompfvf_intr_handler, dev);
206 : 0 : tmp = hw->risc_intr + (ZXDH_MSIX_FROM_RISCV - ZXDH_MSIX_INTR_MSG_VEC_BASE);
207 : 0 : rte_intr_callback_unregister(tmp, zxdh_fromriscv_intr_handler, dev);
208 : 0 : }
209 : :
210 : : static int32_t
211 : 0 : zxdh_intr_disable(struct rte_eth_dev *dev)
212 : : {
213 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
214 : :
215 [ # # ]: 0 : if (!hw->intr_enabled)
216 : : return 0;
217 : :
218 : 0 : zxdh_intr_cb_unreg(dev);
219 [ # # ]: 0 : if (rte_intr_disable(dev->intr_handle) < 0)
220 : : return -1;
221 : :
222 : 0 : hw->intr_enabled = 0;
223 : 0 : return 0;
224 : : }
225 : :
226 : : static int32_t
227 : 0 : zxdh_intr_enable(struct rte_eth_dev *dev)
228 : : {
229 : : int ret = 0;
230 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
231 : :
232 [ # # ]: 0 : if (!hw->intr_enabled) {
233 : 0 : zxdh_intr_cb_reg(dev);
234 : 0 : ret = rte_intr_enable(dev->intr_handle);
235 [ # # ]: 0 : if (unlikely(ret))
236 : 0 : PMD_DRV_LOG(ERR, "Failed to enable %s intr", dev->data->name);
237 : :
238 : 0 : hw->intr_enabled = 1;
239 : : }
240 : 0 : return ret;
241 : : }
242 : :
243 : : static int32_t
244 : 0 : zxdh_intr_release(struct rte_eth_dev *dev)
245 : : {
246 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
247 : :
248 [ # # ]: 0 : if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
249 : 0 : ZXDH_VTPCI_OPS(hw)->set_config_irq(hw, ZXDH_MSI_NO_VECTOR);
250 : :
251 : 0 : zxdh_queues_unbind_intr(dev);
252 : 0 : zxdh_intr_disable(dev);
253 : :
254 : 0 : rte_intr_efd_disable(dev->intr_handle);
255 : 0 : rte_intr_vec_list_free(dev->intr_handle);
256 : 0 : rte_free(hw->risc_intr);
257 : 0 : hw->risc_intr = NULL;
258 : 0 : rte_free(hw->dtb_intr);
259 : 0 : hw->dtb_intr = NULL;
260 : 0 : return 0;
261 : : }
262 : :
263 : : static int32_t
264 : 0 : zxdh_setup_risc_interrupts(struct rte_eth_dev *dev)
265 : : {
266 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
267 : : uint8_t i;
268 : :
269 [ # # ]: 0 : if (!hw->risc_intr) {
270 : 0 : PMD_DRV_LOG(ERR, "to allocate risc_intr");
271 : 0 : hw->risc_intr = rte_zmalloc("risc_intr",
272 : : ZXDH_MSIX_INTR_MSG_VEC_NUM * sizeof(struct rte_intr_handle), 0);
273 [ # # ]: 0 : if (hw->risc_intr == NULL) {
274 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate risc_intr");
275 : 0 : return -ENOMEM;
276 : : }
277 : : }
278 : :
279 [ # # ]: 0 : for (i = 0; i < ZXDH_MSIX_INTR_MSG_VEC_NUM; i++) {
280 [ # # ]: 0 : if (dev->intr_handle->efds[i] < 0) {
281 : 0 : PMD_DRV_LOG(ERR, "[%u]risc interrupt fd is invalid", i);
282 : 0 : rte_free(hw->risc_intr);
283 : 0 : hw->risc_intr = NULL;
284 : 0 : return -1;
285 : : }
286 : :
287 : 0 : struct rte_intr_handle *intr_handle = hw->risc_intr + i;
288 : :
289 : 0 : intr_handle->fd = dev->intr_handle->efds[i];
290 : 0 : intr_handle->type = dev->intr_handle->type;
291 : : }
292 : :
293 : : return 0;
294 : : }
295 : :
296 : : static int32_t
297 : 0 : zxdh_setup_dtb_interrupts(struct rte_eth_dev *dev)
298 : : {
299 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
300 : :
301 [ # # ]: 0 : if (!hw->dtb_intr) {
302 : 0 : hw->dtb_intr = rte_zmalloc("dtb_intr", sizeof(struct rte_intr_handle), 0);
303 [ # # ]: 0 : if (hw->dtb_intr == NULL) {
304 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate dtb_intr");
305 : 0 : return -ENOMEM;
306 : : }
307 : : }
308 : :
309 [ # # ]: 0 : if (dev->intr_handle->efds[ZXDH_MSIX_INTR_DTB_VEC - 1] < 0) {
310 : 0 : PMD_DRV_LOG(ERR, "[%d]dtb interrupt fd is invalid", ZXDH_MSIX_INTR_DTB_VEC - 1);
311 : 0 : rte_free(hw->dtb_intr);
312 : 0 : hw->dtb_intr = NULL;
313 : 0 : return -1;
314 : : }
315 : 0 : hw->dtb_intr->fd = dev->intr_handle->efds[ZXDH_MSIX_INTR_DTB_VEC - 1];
316 : 0 : hw->dtb_intr->type = dev->intr_handle->type;
317 : 0 : return 0;
318 : : }
319 : :
320 : : static int32_t
321 : 0 : zxdh_queues_bind_intr(struct rte_eth_dev *dev)
322 : : {
323 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
324 : : int32_t i;
325 : : uint16_t vec;
326 : :
327 [ # # ]: 0 : if (!dev->data->dev_conf.intr_conf.rxq) {
328 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; ++i) {
329 : 0 : vec = ZXDH_VTPCI_OPS(hw)->set_queue_irq(hw,
330 : 0 : hw->vqs[i * 2], ZXDH_MSI_NO_VECTOR);
331 : 0 : PMD_DRV_LOG(DEBUG, "vq%d irq set 0x%x, get 0x%x",
332 : : i * 2, ZXDH_MSI_NO_VECTOR, vec);
333 : : }
334 : : } else {
335 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; ++i) {
336 : 0 : vec = ZXDH_VTPCI_OPS(hw)->set_queue_irq(hw,
337 : 0 : hw->vqs[i * 2], i + ZXDH_QUEUE_INTR_VEC_BASE);
338 : 0 : PMD_DRV_LOG(DEBUG, "vq%d irq set %d, get %d",
339 : : i * 2, i + ZXDH_QUEUE_INTR_VEC_BASE, vec);
340 : : }
341 : : }
342 : : /* mask all txq intr */
343 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; ++i) {
344 : 0 : vec = ZXDH_VTPCI_OPS(hw)->set_queue_irq(hw,
345 : 0 : hw->vqs[(i * 2) + 1], ZXDH_MSI_NO_VECTOR);
346 : 0 : PMD_DRV_LOG(DEBUG, "vq%d irq set 0x%x, get 0x%x",
347 : : (i * 2) + 1, ZXDH_MSI_NO_VECTOR, vec);
348 : : }
349 : 0 : return 0;
350 : : }
351 : :
352 : : static int32_t
353 : 0 : zxdh_configure_intr(struct rte_eth_dev *dev)
354 : : {
355 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
356 : : int32_t ret = 0;
357 : :
358 [ # # ]: 0 : if (!rte_intr_cap_multiple(dev->intr_handle)) {
359 : 0 : PMD_DRV_LOG(ERR, "Multiple intr vector not supported");
360 : 0 : return -ENOTSUP;
361 : : }
362 : 0 : zxdh_intr_release(dev);
363 : : uint8_t nb_efd = ZXDH_MSIX_INTR_DTB_VEC_NUM + ZXDH_MSIX_INTR_MSG_VEC_NUM;
364 : :
365 [ # # ]: 0 : if (dev->data->dev_conf.intr_conf.rxq)
366 : 0 : nb_efd += dev->data->nb_rx_queues;
367 : :
368 [ # # ]: 0 : if (rte_intr_efd_enable(dev->intr_handle, nb_efd)) {
369 : 0 : PMD_DRV_LOG(ERR, "Fail to create eventfd");
370 : 0 : return -1;
371 : : }
372 : :
373 [ # # ]: 0 : if (rte_intr_vec_list_alloc(dev->intr_handle, "intr_vec",
374 : 0 : hw->max_queue_pairs + ZXDH_INTR_NONQUE_NUM)) {
375 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate %u rxq vectors",
376 : : hw->max_queue_pairs + ZXDH_INTR_NONQUE_NUM);
377 : 0 : return -ENOMEM;
378 : : }
379 : 0 : PMD_DRV_LOG(DEBUG, "allocate %u rxq vectors", dev->intr_handle->vec_list_size);
380 [ # # ]: 0 : if (zxdh_setup_risc_interrupts(dev) != 0) {
381 : 0 : PMD_DRV_LOG(ERR, "Error setting up rsic_v interrupts!");
382 : : ret = -1;
383 : 0 : goto free_intr_vec;
384 : : }
385 [ # # ]: 0 : if (zxdh_setup_dtb_interrupts(dev) != 0) {
386 : 0 : PMD_DRV_LOG(ERR, "Error setting up dtb interrupts!");
387 : : ret = -1;
388 : 0 : goto free_intr_vec;
389 : : }
390 : :
391 [ # # ]: 0 : if (zxdh_queues_bind_intr(dev) < 0) {
392 : 0 : PMD_DRV_LOG(ERR, "Failed to bind queue/interrupt");
393 : : ret = -1;
394 : 0 : goto free_intr_vec;
395 : : }
396 : :
397 [ # # ]: 0 : if (zxdh_intr_enable(dev) < 0) {
398 : 0 : PMD_DRV_LOG(ERR, "interrupt enable failed");
399 : : ret = -1;
400 : 0 : goto free_intr_vec;
401 : : }
402 : : return 0;
403 : :
404 : 0 : free_intr_vec:
405 : 0 : zxdh_intr_release(dev);
406 : 0 : return ret;
407 : : }
408 : :
409 : : static void
410 : 0 : zxdh_update_net_hdr_dl(struct zxdh_hw *hw)
411 : : {
412 : 0 : struct zxdh_net_hdr_dl *net_hdr_dl = hw->net_hdr_dl;
413 : : memset(net_hdr_dl, 0, ZXDH_DL_NET_HDR_SIZE);
414 : :
415 [ # # ]: 0 : if (zxdh_tx_offload_enabled(hw)) {
416 : 0 : net_hdr_dl->type_hdr.port = ZXDH_PORT_DTP;
417 : 0 : net_hdr_dl->type_hdr.pd_len = ZXDH_DL_NET_HDR_SIZE >> 1;
418 : :
419 : 0 : net_hdr_dl->pipd_hdr_dl.pi_hdr.pi_len = (ZXDH_PI_HDR_SIZE >> 4) - 1;
420 : 0 : net_hdr_dl->pipd_hdr_dl.pi_hdr.pkt_flag_hi8 = ZXDH_PI_FLAG | ZXDH_PI_TYPE_PI;
421 : 0 : net_hdr_dl->pipd_hdr_dl.pi_hdr.pkt_type = ZXDH_PKT_FORM_CPU;
422 : 0 : hw->dl_net_hdr_len = ZXDH_DL_NET_HDR_SIZE;
423 : :
424 : : } else {
425 : 0 : net_hdr_dl->type_hdr.port = ZXDH_PORT_NP;
426 : 0 : net_hdr_dl->type_hdr.pd_len = ZXDH_DL_NET_HDR_NOPI_SIZE >> 1;
427 : 0 : hw->dl_net_hdr_len = ZXDH_DL_NET_HDR_NOPI_SIZE;
428 : : }
429 : 0 : }
430 : :
431 : : static int32_t
432 : 0 : zxdh_features_update(struct zxdh_hw *hw,
433 : : const struct rte_eth_rxmode *rxmode,
434 : : const struct rte_eth_txmode *txmode)
435 : : {
436 : 0 : uint64_t rx_offloads = rxmode->offloads;
437 : 0 : uint64_t tx_offloads = txmode->offloads;
438 : 0 : uint64_t req_features = hw->guest_features;
439 : :
440 [ # # ]: 0 : if (rx_offloads & (RTE_ETH_RX_OFFLOAD_UDP_CKSUM | RTE_ETH_RX_OFFLOAD_TCP_CKSUM))
441 : 0 : req_features |= (1ULL << ZXDH_NET_F_GUEST_CSUM);
442 : :
443 [ # # ]: 0 : if (rx_offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO)
444 : 0 : req_features |= (1ULL << ZXDH_NET_F_GUEST_TSO4) |
445 : : (1ULL << ZXDH_NET_F_GUEST_TSO6);
446 : :
447 [ # # ]: 0 : if (tx_offloads & (RTE_ETH_RX_OFFLOAD_UDP_CKSUM | RTE_ETH_RX_OFFLOAD_TCP_CKSUM))
448 : 0 : req_features |= (1ULL << ZXDH_NET_F_CSUM);
449 : :
450 [ # # ]: 0 : if (tx_offloads & RTE_ETH_TX_OFFLOAD_TCP_TSO)
451 : 0 : req_features |= (1ULL << ZXDH_NET_F_HOST_TSO4) |
452 : : (1ULL << ZXDH_NET_F_HOST_TSO6);
453 : :
454 [ # # ]: 0 : if (tx_offloads & RTE_ETH_TX_OFFLOAD_UDP_TSO)
455 : 0 : req_features |= (1ULL << ZXDH_NET_F_HOST_UFO);
456 : :
457 : 0 : req_features = req_features & hw->host_features;
458 : 0 : hw->guest_features = req_features;
459 : :
460 : 0 : ZXDH_VTPCI_OPS(hw)->set_features(hw, req_features);
461 : :
462 [ # # # # ]: 0 : if ((rx_offloads & (RTE_ETH_TX_OFFLOAD_UDP_CKSUM | RTE_ETH_TX_OFFLOAD_TCP_CKSUM)) &&
463 : : !zxdh_pci_with_feature(hw, ZXDH_NET_F_GUEST_CSUM)) {
464 : 0 : PMD_DRV_LOG(ERR, "rx checksum not available on this host");
465 : 0 : return -ENOTSUP;
466 : : }
467 : :
468 [ # # # # ]: 0 : if ((rx_offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) &&
469 [ # # ]: 0 : (!zxdh_pci_with_feature(hw, ZXDH_NET_F_GUEST_TSO4) ||
470 : : !zxdh_pci_with_feature(hw, ZXDH_NET_F_GUEST_TSO6))) {
471 : 0 : PMD_DRV_LOG(ERR, "Large Receive Offload not available on this host");
472 : 0 : return -ENOTSUP;
473 : : }
474 : : return 0;
475 : : }
476 : :
477 : : static void
478 : 0 : zxdh_dev_free_mbufs(struct rte_eth_dev *dev)
479 : : {
480 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
481 : : struct zxdh_virtqueue *vq;
482 : : struct rte_mbuf *buf;
483 : : int i;
484 : :
485 [ # # ]: 0 : if (hw->vqs == NULL)
486 : : return;
487 : :
488 [ # # ]: 0 : for (i = 0; i < hw->rx_qnum; i++) {
489 : 0 : vq = hw->vqs[i * 2];
490 [ # # ]: 0 : if (!vq)
491 : 0 : continue;
492 [ # # ]: 0 : while ((buf = zxdh_queue_detach_unused(vq)) != NULL)
493 : 0 : rte_pktmbuf_free(buf);
494 : 0 : PMD_DRV_LOG(DEBUG, "freeing %s[%d] used and unused buf",
495 : : "rxq", i * 2);
496 : : }
497 [ # # ]: 0 : for (i = 0; i < hw->tx_qnum; i++) {
498 : 0 : vq = hw->vqs[i * 2 + 1];
499 [ # # ]: 0 : if (!vq)
500 : 0 : continue;
501 [ # # ]: 0 : while ((buf = zxdh_queue_detach_unused(vq)) != NULL)
502 : 0 : rte_pktmbuf_free(buf);
503 : 0 : PMD_DRV_LOG(DEBUG, "freeing %s[%d] used and unused buf",
504 : : "txq", i * 2 + 1);
505 : : }
506 : : }
507 : :
508 : : static int32_t
509 : 0 : zxdh_get_available_channel(struct rte_eth_dev *dev, uint8_t queue_type)
510 : : {
511 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
512 : 0 : uint16_t base = (queue_type == ZXDH_VTNET_RQ) ? 0 : 1; /* txq only polls odd bits*/
513 : : uint16_t j = 0;
514 : : uint16_t done = 0;
515 : : uint32_t phy_vq_reg = 0;
516 : 0 : uint16_t total_queue_num = hw->queue_pool_count * 2;
517 : 0 : uint16_t start_qp_id = hw->queue_pool_start * 2;
518 : 0 : uint32_t phy_vq_reg_oft = start_qp_id / 32;
519 : 0 : uint32_t inval_bit = start_qp_id % 32;
520 : 0 : uint32_t res_bit = (total_queue_num + inval_bit) % 32;
521 [ # # ]: 0 : uint32_t vq_reg_num = (total_queue_num + inval_bit) / 32 + (res_bit ? 1 : 0);
522 : : int32_t ret = 0;
523 : : uint32_t addr = 0;
524 : : uint32_t var = 0;
525 : : int32_t ph_chno = 0;
526 : :
527 : 0 : ret = zxdh_timedlock(hw, 1000);
528 [ # # ]: 0 : if (ret) {
529 : 0 : PMD_DRV_LOG(ERR, "Acquiring hw lock got failed, timeout");
530 : 0 : return -1;
531 : : }
532 : :
533 [ # # ]: 0 : for (phy_vq_reg = 0; phy_vq_reg < vq_reg_num; phy_vq_reg++) {
534 : 0 : addr = ZXDH_QUERES_SHARE_BASE +
535 : 0 : (phy_vq_reg + phy_vq_reg_oft) * sizeof(uint32_t);
536 : 0 : var = zxdh_read_bar_reg(dev, ZXDH_BAR0_INDEX, addr);
537 [ # # ]: 0 : if (phy_vq_reg == 0) {
538 [ # # ]: 0 : for (j = (inval_bit + base); j < 32; j += 2) {
539 : : /* Got the available channel & update COI table */
540 [ # # ]: 0 : if ((var & (1 << j)) == 0) {
541 : 0 : var |= (1 << j);
542 : : done = 1;
543 : : break;
544 : : }
545 : : }
546 : : if (done)
547 : : break;
548 [ # # # # ]: 0 : } else if ((phy_vq_reg == (vq_reg_num - 1)) && (res_bit != 0)) {
549 [ # # ]: 0 : for (j = base; j < res_bit; j += 2) {
550 : : /* Got the available channel & update COI table */
551 [ # # ]: 0 : if ((var & (1 << j)) == 0) {
552 : 0 : var |= (1 << j);
553 : : done = 1;
554 : : break;
555 : : }
556 : : }
557 : : if (done)
558 : : break;
559 : : } else {
560 [ # # ]: 0 : for (j = base; j < 32; j += 2) {
561 : : /* Got the available channel & update COI table */
562 [ # # ]: 0 : if ((var & (1 << j)) == 0) {
563 : 0 : var |= (1 << j);
564 : : done = 1;
565 : : break;
566 : : }
567 : : }
568 : : if (done)
569 : : break;
570 : : }
571 : : }
572 : :
573 [ # # ]: 0 : if (done) {
574 : 0 : ph_chno = (phy_vq_reg + phy_vq_reg_oft) * 32 + j;
575 [ # # ]: 0 : if (zxdh_datach_set(dev, ph_chno) != 0) {
576 : 0 : zxdh_release_lock(hw);
577 : 0 : PMD_DRV_LOG(ERR, "zxdh_datach_set queue pcie addr failed");
578 : 0 : return -1;
579 : : }
580 : 0 : zxdh_write_bar_reg(dev, ZXDH_BAR0_INDEX, addr, var);
581 : : }
582 : :
583 : 0 : zxdh_release_lock(hw);
584 : : /* check for no channel condition */
585 [ # # ]: 0 : if (done != 1) {
586 : 0 : PMD_DRV_LOG(ERR, "NO availd queues");
587 : 0 : return -1;
588 : : }
589 : : /* reruen available channel ID */
590 : 0 : return (phy_vq_reg + phy_vq_reg_oft) * 32 + j;
591 : : }
592 : :
593 : : static int32_t
594 : 0 : zxdh_acquire_channel(struct rte_eth_dev *dev, uint16_t lch)
595 : : {
596 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
597 : :
598 [ # # ]: 0 : if (hw->channel_context[lch].valid == 1) {
599 : 0 : PMD_DRV_LOG(DEBUG, "Logic channel:%u already acquired Physics channel:%u",
600 : : lch, hw->channel_context[lch].ph_chno);
601 : 0 : return hw->channel_context[lch].ph_chno;
602 : : }
603 : 0 : int32_t pch = zxdh_get_available_channel(dev, zxdh_get_queue_type(lch));
604 : :
605 [ # # ]: 0 : if (pch < 0) {
606 : 0 : PMD_DRV_LOG(ERR, "Failed to acquire channel");
607 : 0 : return -1;
608 : : }
609 : 0 : hw->channel_context[lch].ph_chno = (uint16_t)pch;
610 : 0 : hw->channel_context[lch].valid = 1;
611 : 0 : PMD_DRV_LOG(DEBUG, "Acquire channel success lch:%u --> pch:%d", lch, pch);
612 : 0 : return 0;
613 : : }
614 : :
615 : : static void
616 : 0 : zxdh_init_vring(struct zxdh_virtqueue *vq)
617 : : {
618 : 0 : int32_t size = vq->vq_nentries;
619 : 0 : uint8_t *ring_mem = vq->vq_ring_virt_mem;
620 : :
621 : 0 : memset(ring_mem, 0, vq->vq_ring_size);
622 : :
623 : 0 : vq->vq_used_cons_idx = 0;
624 : 0 : vq->vq_desc_head_idx = 0;
625 : 0 : vq->vq_avail_idx = 0;
626 : 0 : vq->vq_desc_tail_idx = (uint16_t)(vq->vq_nentries - 1);
627 : 0 : vq->vq_free_cnt = vq->vq_nentries;
628 : 0 : memset(vq->vq_descx, 0, sizeof(struct zxdh_vq_desc_extra) * vq->vq_nentries);
629 : 0 : zxdh_vring_init_packed(&vq->vq_packed.ring, ring_mem, ZXDH_PCI_VRING_ALIGN, size);
630 : : zxdh_vring_desc_init_packed(vq, size);
631 : : zxdh_queue_disable_intr(vq);
632 : 0 : }
633 : :
634 : : static int32_t
635 : 0 : zxdh_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_logic_qidx)
636 : : {
637 : 0 : char vq_name[ZXDH_VIRTQUEUE_MAX_NAME_SZ] = {0};
638 : 0 : char vq_hdr_name[ZXDH_VIRTQUEUE_MAX_NAME_SZ] = {0};
639 : : const struct rte_memzone *mz = NULL;
640 : : const struct rte_memzone *hdr_mz = NULL;
641 : : uint32_t size = 0;
642 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
643 : : struct zxdh_virtnet_rx *rxvq = NULL;
644 : : struct zxdh_virtnet_tx *txvq = NULL;
645 : : struct zxdh_virtqueue *vq = NULL;
646 : : size_t sz_hdr_mz = 0;
647 : : void *sw_ring = NULL;
648 : 0 : int32_t queue_type = zxdh_get_queue_type(vtpci_logic_qidx);
649 : 0 : int32_t numa_node = dev->device->numa_node;
650 : : uint16_t vtpci_phy_qidx = 0;
651 : : uint32_t vq_size = 0;
652 : : int32_t ret = 0;
653 : :
654 [ # # ]: 0 : if (vtpci_logic_qidx >= ZXDH_QUEUES_NUM_MAX ||
655 [ # # ]: 0 : hw->channel_context[vtpci_logic_qidx].valid == 0) {
656 : 0 : PMD_DRV_LOG(ERR, "lch %d is invalid", vtpci_logic_qidx);
657 : 0 : return -EINVAL;
658 : : }
659 : 0 : vtpci_phy_qidx = hw->channel_context[vtpci_logic_qidx].ph_chno;
660 : :
661 : 0 : PMD_DRV_LOG(DEBUG, "vtpci_logic_qidx :%d setting up physical queue: %u on NUMA node %d",
662 : : vtpci_logic_qidx, vtpci_phy_qidx, numa_node);
663 : :
664 [ # # ]: 0 : if (queue_type == ZXDH_VTNET_RQ)
665 : 0 : vq_size = hw->queue_conf->conf[vtpci_logic_qidx >> 1].rx_nb_desc;
666 : : else
667 : 0 : vq_size = hw->queue_conf->conf[vtpci_logic_qidx >> 1].tx_nb_desc;
668 : :
669 [ # # ]: 0 : if (ZXDH_VTPCI_OPS(hw)->set_queue_num != NULL)
670 : 0 : ZXDH_VTPCI_OPS(hw)->set_queue_num(hw, vtpci_phy_qidx, vq_size);
671 : :
672 [ # # ]: 0 : snprintf(vq_name, sizeof(vq_name), "port%d_vq%d", dev->data->port_id, vtpci_phy_qidx);
673 : :
674 : 0 : size = RTE_ALIGN_CEIL(sizeof(*vq) + vq_size * sizeof(struct zxdh_vq_desc_extra),
675 : : RTE_CACHE_LINE_SIZE);
676 [ # # ]: 0 : if (queue_type == ZXDH_VTNET_TQ) {
677 : : /*
678 : : * For each xmit packet, allocate a zxdh_net_hdr
679 : : * and indirect ring elements
680 : : */
681 : 0 : sz_hdr_mz = vq_size * sizeof(struct zxdh_tx_region);
682 : : }
683 : :
684 : 0 : vq = rte_zmalloc_socket(vq_name, size, RTE_CACHE_LINE_SIZE, numa_node);
685 [ # # ]: 0 : if (vq == NULL) {
686 : 0 : PMD_DRV_LOG(ERR, "can not allocate vq");
687 : 0 : return -ENOMEM;
688 : : }
689 : 0 : hw->vqs[vtpci_logic_qidx] = vq;
690 : :
691 : 0 : vq->hw = hw;
692 : 0 : vq->vq_queue_index = vtpci_phy_qidx;
693 : 0 : vq->vq_nentries = vq_size;
694 : :
695 : 0 : vq->vq_packed.used_wrap_counter = 1;
696 : 0 : vq->vq_packed.cached_flags = ZXDH_VRING_PACKED_DESC_F_AVAIL;
697 : 0 : vq->vq_packed.event_flags_shadow = 0;
698 [ # # ]: 0 : if (queue_type == ZXDH_VTNET_RQ)
699 : 0 : vq->vq_packed.cached_flags |= ZXDH_VRING_DESC_F_WRITE;
700 : :
701 : : /*
702 : : * Reserve a memzone for vring elements
703 : : */
704 : 0 : size = zxdh_vring_size(hw, vq_size, ZXDH_PCI_VRING_ALIGN);
705 : 0 : vq->vq_ring_size = RTE_ALIGN_CEIL(size, ZXDH_PCI_VRING_ALIGN);
706 : 0 : PMD_DRV_LOG(DEBUG, "vring_size: %d, rounded_vring_size: %d", size, vq->vq_ring_size);
707 : :
708 : 0 : mz = rte_memzone_reserve_aligned(vq_name, vq->vq_ring_size,
709 : : numa_node, RTE_MEMZONE_IOVA_CONTIG,
710 : : ZXDH_PCI_VRING_ALIGN);
711 [ # # ]: 0 : if (mz == NULL) {
712 [ # # ]: 0 : if (rte_errno == EEXIST)
713 : 0 : mz = rte_memzone_lookup(vq_name);
714 [ # # ]: 0 : if (mz == NULL) {
715 : : ret = -ENOMEM;
716 : 0 : goto fail_q_alloc;
717 : : }
718 : : }
719 : :
720 : 0 : memset(mz->addr, 0, mz->len);
721 : :
722 : 0 : vq->vq_ring_mem = mz->iova;
723 : 0 : vq->vq_ring_virt_mem = mz->addr;
724 : :
725 : 0 : zxdh_init_vring(vq);
726 : :
727 [ # # ]: 0 : if (sz_hdr_mz) {
728 : 0 : snprintf(vq_hdr_name, sizeof(vq_hdr_name), "port%d_vq%d_hdr",
729 : 0 : dev->data->port_id, vtpci_phy_qidx);
730 : 0 : hdr_mz = rte_memzone_reserve_aligned(vq_hdr_name, sz_hdr_mz,
731 : : numa_node, RTE_MEMZONE_IOVA_CONTIG,
732 : : RTE_CACHE_LINE_SIZE);
733 [ # # ]: 0 : if (hdr_mz == NULL) {
734 [ # # ]: 0 : if (rte_errno == EEXIST)
735 : 0 : hdr_mz = rte_memzone_lookup(vq_hdr_name);
736 [ # # ]: 0 : if (hdr_mz == NULL) {
737 : : ret = -ENOMEM;
738 : 0 : goto fail_q_alloc;
739 : : }
740 : : }
741 : : }
742 : :
743 [ # # ]: 0 : if (queue_type == ZXDH_VTNET_RQ) {
744 : 0 : size_t sz_sw = (ZXDH_MBUF_BURST_SZ + vq_size) * sizeof(vq->sw_ring[0]);
745 : :
746 : 0 : sw_ring = rte_zmalloc_socket("sw_ring", sz_sw, RTE_CACHE_LINE_SIZE, numa_node);
747 [ # # ]: 0 : if (!sw_ring) {
748 : 0 : PMD_DRV_LOG(ERR, "can not allocate RX soft ring");
749 : : ret = -ENOMEM;
750 : 0 : goto fail_q_alloc;
751 : : }
752 : :
753 : 0 : vq->sw_ring = sw_ring;
754 : : rxvq = &vq->rxq;
755 : 0 : rxvq->vq = vq;
756 : 0 : rxvq->port_id = dev->data->port_id;
757 : 0 : rxvq->mz = mz;
758 : : } else { /* queue_type == VTNET_TQ */
759 : 0 : txvq = &vq->txq;
760 : 0 : txvq->vq = vq;
761 : 0 : txvq->port_id = dev->data->port_id;
762 : 0 : txvq->mz = mz;
763 : 0 : txvq->zxdh_net_hdr_mz = hdr_mz;
764 : 0 : txvq->zxdh_net_hdr_mem = hdr_mz->iova;
765 : : }
766 : :
767 : 0 : vq->offset = offsetof(struct rte_mbuf, buf_iova);
768 [ # # ]: 0 : if (queue_type == ZXDH_VTNET_TQ) {
769 : 0 : struct zxdh_tx_region *txr = hdr_mz->addr;
770 : : uint32_t i;
771 : :
772 : 0 : memset(txr, 0, vq_size * sizeof(*txr));
773 [ # # ]: 0 : for (i = 0; i < vq_size; i++) {
774 : : /* first indirect descriptor is always the tx header */
775 : 0 : struct zxdh_vring_packed_desc *start_dp = txr[i].tx_packed_indir;
776 : :
777 : : zxdh_vring_desc_init_indirect_packed(start_dp,
778 : : RTE_DIM(txr[i].tx_packed_indir));
779 : 0 : start_dp->addr = txvq->zxdh_net_hdr_mem + i * sizeof(*txr) +
780 : : offsetof(struct zxdh_tx_region, tx_hdr);
781 : : /* length will be updated to actual pi hdr size when xmit pkt */
782 : 0 : start_dp->len = 0;
783 : : }
784 : : }
785 [ # # ]: 0 : if (ZXDH_VTPCI_OPS(hw)->setup_queue(hw, vq) < 0) {
786 : 0 : PMD_DRV_LOG(ERR, "setup_queue failed");
787 : 0 : return -EINVAL;
788 : : }
789 : : return 0;
790 : 0 : fail_q_alloc:
791 : 0 : rte_free(sw_ring);
792 : 0 : rte_memzone_free(hdr_mz);
793 : 0 : rte_memzone_free(mz);
794 : 0 : rte_free(vq);
795 : 0 : return ret;
796 : : }
797 : :
798 : : static int
799 : 0 : zxdh_inic_pf_init_qid(struct zxdh_hw *hw)
800 : : {
801 : : uint16_t start_qid, enabled_qp;
802 : 0 : int ret = zxdh_inic_pf_get_qp_from_vcb(hw, hw->vfid, &start_qid, &enabled_qp);
803 : :
804 [ # # ]: 0 : if (ret != 0) {
805 : 0 : PMD_DRV_LOG(ERR, "vqm_vfid %u, get_qp_from_vcb fail", hw->vfid);
806 : 0 : return ret;
807 : : }
808 : :
809 : 0 : uint16_t i, num_queues = rte_read16(&hw->common_cfg->num_queues);
810 [ # # ]: 0 : PMD_DRV_LOG(INFO, "vqm_vfid:%u, get num_queues:%u (%s CQ)",
811 : : hw->vfid, num_queues, (num_queues & 0x1) ? "with" : "without");
812 [ # # ]: 0 : for (i = 0; i < (num_queues & 0xfffe); ++i) {
813 : 0 : hw->channel_context[i].ph_chno = start_qid + i;
814 : 0 : hw->channel_context[i].valid = 1;
815 : : }
816 : : return 0;
817 : : }
818 : :
819 : : static int32_t
820 : 0 : zxdh_alloc_queues(struct rte_eth_dev *dev)
821 : : {
822 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
823 : 0 : u_int16_t rxq_num = hw->rx_qnum;
824 : 0 : u_int16_t txq_num = hw->tx_qnum;
825 [ # # ]: 0 : uint16_t nr_vq = (rxq_num > txq_num) ? 2 * rxq_num : 2 * txq_num;
826 : 0 : hw->vqs = rte_zmalloc(NULL, sizeof(struct zxdh_virtqueue *) * nr_vq, 0);
827 : : uint16_t lch, i;
828 : :
829 [ # # ]: 0 : if (!hw->vqs) {
830 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate %d vqs", nr_vq);
831 : 0 : return -ENOMEM;
832 : : }
833 : :
834 [ # # # # ]: 0 : if (hw->switchoffload && !(hw->host_features & (1ULL << ZXDH_F_RING_PACKED))) {
835 [ # # ]: 0 : if (zxdh_inic_pf_init_qid(hw) != 0)
836 : 0 : goto free;
837 : :
838 [ # # ]: 0 : for (i = 0 ; i < rxq_num; i++) {
839 : 0 : lch = i * 2;
840 [ # # ]: 0 : if (zxdh_init_queue(dev, lch) < 0) {
841 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc virtio queue");
842 : 0 : goto free;
843 : : }
844 : : }
845 [ # # ]: 0 : for (i = 0 ; i < txq_num; i++) {
846 : 0 : lch = i * 2 + 1;
847 [ # # ]: 0 : if (zxdh_init_queue(dev, lch) < 0) {
848 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc virtio queue");
849 : 0 : goto free;
850 : : }
851 : : }
852 : : return 0;
853 : : }
854 : :
855 [ # # ]: 0 : for (i = 0 ; i < rxq_num; i++) {
856 : 0 : lch = i * 2;
857 [ # # ]: 0 : if (zxdh_acquire_channel(dev, lch) < 0) {
858 : 0 : PMD_DRV_LOG(ERR, "Failed to acquire the channels");
859 : 0 : goto free;
860 : : }
861 [ # # ]: 0 : if (zxdh_init_queue(dev, lch) < 0) {
862 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc virtio queue");
863 : 0 : goto free;
864 : : }
865 : : }
866 [ # # ]: 0 : for (i = 0 ; i < txq_num; i++) {
867 : 0 : lch = i * 2 + 1;
868 [ # # ]: 0 : if (zxdh_acquire_channel(dev, lch) < 0) {
869 : 0 : PMD_DRV_LOG(ERR, "Failed to acquire the channels");
870 : 0 : goto free;
871 : : }
872 [ # # ]: 0 : if (zxdh_init_queue(dev, lch) < 0) {
873 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc virtio queue");
874 : 0 : goto free;
875 : : }
876 : : }
877 : : return 0;
878 : :
879 : 0 : free:
880 : 0 : zxdh_free_queues(dev);
881 : 0 : return -1;
882 : : }
883 : :
884 : : static int
885 : 0 : zxdh_vlan_offload_configure(struct rte_eth_dev *dev)
886 : : {
887 : : int ret;
888 : : int mask = RTE_ETH_VLAN_STRIP_MASK | RTE_ETH_VLAN_FILTER_MASK | RTE_ETH_QINQ_STRIP_MASK;
889 : :
890 : 0 : ret = zxdh_dev_vlan_offload_set(dev, mask);
891 [ # # ]: 0 : if (ret) {
892 : 0 : PMD_DRV_LOG(ERR, "vlan offload set error");
893 : 0 : return -1;
894 : : }
895 : :
896 : : return 0;
897 : : }
898 : :
899 : : static int
900 : 0 : zxdh_rx_csum_lro_offload_configure(struct rte_eth_dev *dev)
901 : : {
902 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
903 : : struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
904 : 0 : uint32_t need_accelerator = rxmode->offloads & (RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
905 : : RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
906 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
907 : : RTE_ETH_RX_OFFLOAD_OUTER_UDP_CKSUM |
908 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
909 : : RTE_ETH_RX_OFFLOAD_TCP_LRO);
910 : : int ret;
911 : :
912 [ # # ]: 0 : if (hw->is_pf) {
913 : 0 : struct zxdh_port_attr_table port_attr = {0};
914 : 0 : zxdh_get_port_attr(hw, hw->vport.vport, &port_attr);
915 : 0 : port_attr.outer_ip_checksum_offload =
916 : 0 : (rxmode->offloads & RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM) ? true : false;
917 : 0 : port_attr.ip_checksum_offload =
918 : 0 : (rxmode->offloads & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM) ? true : false;
919 : 0 : port_attr.tcp_udp_checksum_offload =
920 : 0 : (rxmode->offloads & (RTE_ETH_RX_OFFLOAD_UDP_CKSUM | RTE_ETH_RX_OFFLOAD_TCP_CKSUM))
921 : 0 : ? true : false;
922 : 0 : port_attr.outer_udp_checksum_offload =
923 : 0 : (rxmode->offloads & RTE_ETH_RX_OFFLOAD_OUTER_UDP_CKSUM) ? true : false;
924 : 0 : port_attr.lro_offload =
925 : 0 : (rxmode->offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) ? true : false;
926 : 0 : port_attr.accelerator_offload_flag = need_accelerator ? true : false;
927 : 0 : ret = zxdh_set_port_attr(hw, hw->vport.vport, &port_attr);
928 [ # # ]: 0 : if (ret) {
929 : 0 : PMD_DRV_LOG(ERR, "%s set port attr failed", __func__);
930 : 0 : return -1;
931 : : }
932 : : } else {
933 : 0 : struct zxdh_msg_info msg_info = {0};
934 : : struct zxdh_port_attr_set_msg *attr_msg = &msg_info.data.port_attr_msg;
935 : :
936 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
937 : 0 : attr_msg->mode = ZXDH_PORT_IP_CHKSUM_FLAG;
938 : 0 : attr_msg->value =
939 : 0 : (rxmode->offloads & RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM) ? true : false;
940 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
941 [ # # ]: 0 : if (ret) {
942 : 0 : PMD_DRV_LOG(ERR, "%s outer ip cksum config failed", __func__);
943 : 0 : return -1;
944 : : }
945 : :
946 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
947 : 0 : attr_msg->mode = ZXDH_PORT_OUTER_IP_CHECKSUM_OFFLOAD_FLAG;
948 : 0 : attr_msg->value = (rxmode->offloads & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM) ? true : false;
949 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
950 [ # # ]: 0 : if (ret) {
951 : 0 : PMD_DRV_LOG(ERR, "%s ip_checksum config failed to send msg", __func__);
952 : 0 : return -1;
953 : : }
954 : :
955 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
956 : 0 : attr_msg->mode = ZXDH_PORT_TCP_UDP_CHKSUM_FLAG;
957 : 0 : attr_msg->value = (rxmode->offloads &
958 : : (RTE_ETH_RX_OFFLOAD_UDP_CKSUM | RTE_ETH_RX_OFFLOAD_TCP_CKSUM)) ?
959 : 0 : true : false;
960 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
961 [ # # ]: 0 : if (ret) {
962 : 0 : PMD_DRV_LOG(ERR, "%s tcp_udp_checksum config failed to send msg", __func__);
963 : 0 : return -1;
964 : : }
965 : :
966 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
967 : 0 : attr_msg->mode = ZXDH_PORT_OUTER_UDP_CHECKSUM_OFFLOAD_FLAG;
968 : 0 : attr_msg->value =
969 : 0 : (rxmode->offloads & RTE_ETH_RX_OFFLOAD_OUTER_UDP_CKSUM) ? true : false;
970 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
971 [ # # ]: 0 : if (ret) {
972 : 0 : PMD_DRV_LOG(ERR,
973 : : "%s outer_udp_checksum offload failed to send msg", __func__);
974 : 0 : return ret;
975 : : }
976 : :
977 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
978 : 0 : attr_msg->mode = ZXDH_PORT_LRO_OFFLOAD_FLAG;
979 : 0 : attr_msg->value = (rxmode->offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) ? true : false;
980 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
981 [ # # ]: 0 : if (ret) {
982 : 0 : PMD_DRV_LOG(ERR, "%s lro offload config failed to send msg", __func__);
983 : 0 : return -1;
984 : : }
985 : :
986 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
987 : 0 : attr_msg->mode = ZXDH_PORT_ACCELERATOR_OFFLOAD_FLAG_FLAG;
988 : 0 : attr_msg->value = need_accelerator ? true : false;
989 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
990 [ # # ]: 0 : if (ret) {
991 : 0 : PMD_DRV_LOG(ERR,
992 : : "%s accelerator offload config failed to send msg", __func__);
993 : 0 : return -1;
994 : : }
995 : : }
996 : :
997 : : return 0;
998 : : }
999 : :
1000 : : static int
1001 : 0 : zxdh_dev_conf_offload(struct rte_eth_dev *dev)
1002 : : {
1003 : : int ret = 0;
1004 : :
1005 : 0 : ret = zxdh_vlan_offload_configure(dev);
1006 [ # # ]: 0 : if (ret) {
1007 : 0 : PMD_DRV_LOG(ERR, "zxdh_vlan_offload_configure failed");
1008 : 0 : return ret;
1009 : : }
1010 : :
1011 : 0 : ret = zxdh_rx_csum_lro_offload_configure(dev);
1012 [ # # ]: 0 : if (ret) {
1013 : 0 : PMD_DRV_LOG(ERR, "rx csum lro configure failed");
1014 : 0 : return ret;
1015 : : }
1016 : :
1017 : : return 0;
1018 : : }
1019 : :
1020 : : static int
1021 : 0 : zxdh_rss_qid_config(struct rte_eth_dev *dev)
1022 : : {
1023 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1024 : 0 : struct zxdh_port_attr_table port_attr = {0};
1025 : 0 : struct zxdh_msg_info msg_info = {0};
1026 : : int ret = 0;
1027 : :
1028 [ # # ]: 0 : if (hw->is_pf) {
1029 : 0 : ret = zxdh_get_port_attr(hw, hw->vport.vport, &port_attr);
1030 : 0 : port_attr.port_base_qid = hw->channel_context[0].ph_chno & 0xfff;
1031 : :
1032 : 0 : ret = zxdh_set_port_attr(hw, hw->vport.vport, &port_attr);
1033 [ # # ]: 0 : if (ret) {
1034 : 0 : PMD_DRV_LOG(ERR, "PF:%d port_base_qid insert failed", hw->vfid);
1035 : 0 : return ret;
1036 : : }
1037 : : } else {
1038 : : struct zxdh_port_attr_set_msg *attr_msg = &msg_info.data.port_attr_msg;
1039 : :
1040 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
1041 : 0 : attr_msg->mode = ZXDH_PORT_BASE_QID_FLAG;
1042 : 0 : attr_msg->value = hw->channel_context[0].ph_chno & 0xfff;
1043 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
1044 [ # # ]: 0 : if (ret) {
1045 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
1046 : : hw->vport.vport, ZXDH_PORT_BASE_QID_FLAG);
1047 : 0 : return ret;
1048 : : }
1049 : : }
1050 : : return ret;
1051 : : }
1052 : :
1053 : : static int32_t
1054 : 0 : zxdh_dev_configure(struct rte_eth_dev *dev)
1055 : : {
1056 : 0 : const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
1057 : 0 : const struct rte_eth_txmode *txmode = &dev->data->dev_conf.txmode;
1058 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1059 : 0 : uint64_t rx_offloads = rxmode->offloads;
1060 : : int32_t ret = 0;
1061 : :
1062 [ # # ]: 0 : if (dev->data->nb_rx_queues > hw->max_queue_pairs ||
1063 [ # # ]: 0 : dev->data->nb_tx_queues > hw->max_queue_pairs) {
1064 : 0 : PMD_DRV_LOG(ERR, "nb_rx_queues=%d or nb_tx_queues=%d must < (%d)!",
1065 : : dev->data->nb_rx_queues, dev->data->nb_tx_queues, hw->max_queue_pairs);
1066 : 0 : return -EINVAL;
1067 : : }
1068 : :
1069 [ # # ]: 0 : if (rxmode->mq_mode != RTE_ETH_MQ_RX_RSS && rxmode->mq_mode != RTE_ETH_MQ_RX_NONE) {
1070 : 0 : PMD_DRV_LOG(ERR, "Unsupported Rx multi queue mode %d", rxmode->mq_mode);
1071 : 0 : return -EINVAL;
1072 : : }
1073 : :
1074 [ # # ]: 0 : if (txmode->mq_mode != RTE_ETH_MQ_TX_NONE) {
1075 : 0 : PMD_DRV_LOG(ERR, "Unsupported Tx multi queue mode %d", txmode->mq_mode);
1076 : 0 : return -EINVAL;
1077 : : }
1078 : : if (rxmode->mq_mode != RTE_ETH_MQ_RX_RSS && rxmode->mq_mode != RTE_ETH_MQ_RX_NONE) {
1079 : : PMD_DRV_LOG(ERR, "Unsupported Rx multi queue mode %d", rxmode->mq_mode);
1080 : : return -EINVAL;
1081 : : }
1082 : :
1083 : : if (txmode->mq_mode != RTE_ETH_MQ_TX_NONE) {
1084 : : PMD_DRV_LOG(ERR, "Unsupported Tx multi queue mode %d", txmode->mq_mode);
1085 : : return -EINVAL;
1086 : : }
1087 : :
1088 : 0 : ret = zxdh_features_update(hw, rxmode, txmode);
1089 [ # # ]: 0 : if (ret < 0)
1090 : : return ret;
1091 : :
1092 : : /* check if lsc interrupt feature is enabled */
1093 [ # # ]: 0 : if (dev->data->dev_conf.intr_conf.lsc) {
1094 [ # # ]: 0 : if (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)) {
1095 : 0 : PMD_DRV_LOG(ERR, "link status not supported by host");
1096 : 0 : return -ENOTSUP;
1097 : : }
1098 : : }
1099 : :
1100 [ # # ]: 0 : if (rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
1101 : 0 : hw->vlan_offload_cfg.vlan_strip = 1;
1102 : :
1103 : 0 : hw->has_tx_offload = zxdh_tx_offload_enabled(hw);
1104 : 0 : hw->has_rx_offload = zxdh_rx_offload_enabled(hw);
1105 : :
1106 : 0 : zxdh_dev_conf_offload(dev);
1107 : 0 : zxdh_update_net_hdr_dl(hw);
1108 : 0 : return ret;
1109 : : }
1110 : :
1111 : : static void
1112 : 0 : zxdh_np_dtb_data_res_free(struct zxdh_hw *hw)
1113 : : {
1114 : 0 : struct rte_eth_dev *dev = hw->eth_dev;
1115 : 0 : struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;
1116 : : int ret;
1117 : : int i;
1118 : :
1119 [ # # # # ]: 0 : if (dtb_data->init_done && dtb_data->bind_device == dev) {
1120 : 0 : ret = zxdh_np_online_uninit(hw->dev_id, dev->data->name, dtb_data->queueid);
1121 [ # # ]: 0 : if (ret)
1122 : 0 : PMD_DRV_LOG(ERR, "%s dpp_np_online_uninstall failed", dev->data->name);
1123 : :
1124 : 0 : hw->dev_nic_sd->dtb_used_num--;
1125 : 0 : dtb_data->init_done = 0;
1126 : 0 : dtb_data->bind_device = NULL;
1127 : : }
1128 : :
1129 : 0 : rte_memzone_free(dtb_data->dtb_table_conf_mz);
1130 : 0 : dtb_data->dtb_table_conf_mz = NULL;
1131 : 0 : rte_memzone_free(dtb_data->dtb_table_dump_mz);
1132 : 0 : dtb_data->dtb_table_dump_mz = NULL;
1133 : :
1134 [ # # ]: 0 : for (i = 0; i < ZXDH_MAX_BASE_DTB_TABLE_COUNT; i++) {
1135 [ # # ]: 0 : if (dtb_data->dtb_table_bulk_dump_mz[i]) {
1136 : 0 : rte_memzone_free(dtb_data->dtb_table_bulk_dump_mz[i]);
1137 : 0 : dtb_data->dtb_table_bulk_dump_mz[i] = NULL;
1138 : : }
1139 : : }
1140 : 0 : }
1141 : :
1142 : : static int
1143 : 0 : zxdh_tbl_entry_online_destroy(struct rte_eth_dev *dev)
1144 : : {
1145 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1146 : 0 : struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;
1147 : : uint32_t sdt_no;
1148 : : int ret = 0;
1149 [ # # ]: 0 : if (!dtb_data->init_done)
1150 : : return ret;
1151 [ # # ]: 0 : if (hw->is_pf) {
1152 : 0 : sdt_no = ZXDH_SDT_L2_ENTRY_TABLE0 + hw->hash_search_index;
1153 : 0 : ret = zxdh_np_dtb_hash_online_delete(hw->dev_id, dtb_data->queueid, sdt_no);
1154 [ # # ]: 0 : if (ret)
1155 : 0 : PMD_DRV_LOG(ERR, "%s sdt_no %d failed. code:%d ",
1156 : : dev->data->name, sdt_no, ret);
1157 : 0 : sdt_no = ZXDH_SDT_MC_TABLE0 + hw->hash_search_index;
1158 : 0 : ret = zxdh_np_dtb_hash_online_delete(hw->dev_id, dtb_data->queueid, sdt_no);
1159 [ # # ]: 0 : if (ret)
1160 : 0 : PMD_DRV_LOG(ERR, "%s sdt_no %d failed. code:%d",
1161 : : dev->data->name, sdt_no, ret);
1162 : : }
1163 : : return ret;
1164 : : }
1165 : :
1166 : : static void
1167 : 0 : zxdh_np_uninit(struct rte_eth_dev *dev)
1168 : : {
1169 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1170 : :
1171 [ # # ]: 0 : if (!hw->is_pf)
1172 : : return;
1173 : :
1174 : 0 : zxdh_tbl_entry_online_destroy(dev);
1175 : 0 : zxdh_np_dtb_data_res_free(hw);
1176 : :
1177 [ # # # # ]: 0 : if (hw->dev_nic_sd->init_done && hw->dev_nic_sd->dtb_used_num == 0) {
1178 : 0 : zxdh_np_soft_res_uninstall(hw->dev_id);
1179 : 0 : hw->dev_nic_sd->init_done = 0;
1180 : : }
1181 : 0 : PMD_DRV_LOG(DEBUG, "zxdh_np_destroy: dtb_used_num %d", hw->dev_nic_sd->dtb_used_num);
1182 : :
1183 : : }
1184 : :
1185 : : static int
1186 : 0 : zxdh_tables_uninit(struct rte_eth_dev *dev)
1187 : : {
1188 : : int ret;
1189 : :
1190 : 0 : ret = zxdh_port_attr_uninit(dev);
1191 [ # # ]: 0 : if (ret) {
1192 : 0 : PMD_DRV_LOG(ERR, "zxdh_port_attr_uninit failed");
1193 : 0 : return ret;
1194 : : }
1195 : :
1196 : 0 : ret = zxdh_promisc_table_uninit(dev);
1197 [ # # ]: 0 : if (ret) {
1198 : 0 : PMD_DRV_LOG(ERR, "uninit promisc_table failed");
1199 : 0 : return ret;
1200 : : }
1201 : :
1202 : : return ret;
1203 : : }
1204 : :
1205 : : static int
1206 : 0 : zxdh_dev_stop(struct rte_eth_dev *dev)
1207 : : {
1208 : : uint16_t i;
1209 : : int ret = 0;
1210 : :
1211 [ # # ]: 0 : if (dev->data->dev_started == 0)
1212 : : return 0;
1213 : :
1214 : 0 : ret = zxdh_intr_disable(dev);
1215 [ # # ]: 0 : if (ret) {
1216 : 0 : PMD_DRV_LOG(ERR, "intr disable failed");
1217 : 0 : goto end;
1218 : : }
1219 : :
1220 : 0 : ret = zxdh_dev_set_link_down(dev);
1221 [ # # ]: 0 : if (ret) {
1222 : 0 : PMD_DRV_LOG(ERR, "set port %s link down failed!", dev->device->name);
1223 : 0 : goto end;
1224 : : }
1225 : :
1226 : 0 : end:
1227 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++)
1228 : 0 : dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
1229 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++)
1230 : 0 : dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
1231 : :
1232 : : return ret;
1233 : : }
1234 : :
1235 : : static void
1236 : 0 : zxdh_priv_res_free(struct zxdh_hw *priv)
1237 : : {
1238 : 0 : rte_free(priv->vfinfo);
1239 : 0 : priv->vfinfo = NULL;
1240 : :
1241 : 0 : rte_free(priv->channel_context);
1242 : 0 : priv->channel_context = NULL;
1243 : :
1244 : 0 : rte_free(priv->queue_conf);
1245 : 0 : priv->queue_conf = NULL;
1246 : :
1247 : 0 : rte_free(priv->net_hdr_dl);
1248 : 0 : priv->net_hdr_dl = NULL;
1249 : 0 : }
1250 : :
1251 : : static int
1252 : 0 : zxdh_dev_close(struct rte_eth_dev *dev)
1253 : : {
1254 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1255 : : int ret = 0;
1256 : :
1257 : 0 : ret = zxdh_dev_stop(dev);
1258 [ # # ]: 0 : if (ret != 0) {
1259 : 0 : PMD_DRV_LOG(ERR, "stop port %s failed.", dev->device->name);
1260 : 0 : return -1;
1261 : : }
1262 : :
1263 : 0 : ret = zxdh_tables_uninit(dev);
1264 [ # # ]: 0 : if (ret != 0) {
1265 : 0 : PMD_DRV_LOG(ERR, "%s :tables uninit %s failed", __func__, dev->device->name);
1266 : 0 : return -1;
1267 : : }
1268 : :
1269 [ # # ]: 0 : if (zxdh_shared_data != NULL) {
1270 : 0 : zxdh_mtr_release(dev);
1271 : 0 : zxdh_flow_release(dev);
1272 : : }
1273 : :
1274 : 0 : zxdh_intr_release(dev);
1275 : 0 : zxdh_np_uninit(dev);
1276 : 0 : zxdh_pci_reset(hw);
1277 : :
1278 : 0 : zxdh_dev_free_mbufs(dev);
1279 : 0 : zxdh_free_queues(dev);
1280 : :
1281 : 0 : zxdh_bar_msg_chan_exit();
1282 : 0 : zxdh_priv_res_free(hw);
1283 : :
1284 : 0 : rte_free(hw->dev_sd);
1285 [ # # ]: 0 : if (dev->data->mac_addrs != NULL) {
1286 : 0 : rte_free(dev->data->mac_addrs);
1287 : 0 : dev->data->mac_addrs = NULL;
1288 : : }
1289 : :
1290 : : return ret;
1291 : : }
1292 : :
1293 : : static int32_t
1294 : 0 : zxdh_set_rxtx_funcs(struct rte_eth_dev *eth_dev)
1295 : : {
1296 [ # # ]: 0 : struct zxdh_hw *hw = eth_dev->data->dev_private;
1297 : :
1298 [ # # ]: 0 : if (!zxdh_pci_with_feature(hw, ZXDH_NET_F_MRG_RXBUF)) {
1299 : 0 : PMD_DRV_LOG(ERR, "port %u not support rx mergeable", eth_dev->data->port_id);
1300 : 0 : return -1;
1301 : : }
1302 : 0 : eth_dev->tx_pkt_prepare = zxdh_xmit_pkts_prepare;
1303 : 0 : eth_dev->tx_pkt_burst = &zxdh_xmit_pkts_packed;
1304 : 0 : eth_dev->rx_pkt_burst = &zxdh_recv_pkts_packed;
1305 : :
1306 : 0 : return 0;
1307 : : }
1308 : :
1309 : : static int
1310 : 0 : zxdh_mac_config(struct rte_eth_dev *eth_dev)
1311 : : {
1312 : 0 : struct zxdh_hw *hw = eth_dev->data->dev_private;
1313 : 0 : struct zxdh_msg_info msg_info = {0};
1314 : : int ret = 0;
1315 : :
1316 [ # # ]: 0 : if (hw->is_pf) {
1317 : 0 : ret = zxdh_add_mac_table(hw, hw->vport.vport,
1318 : 0 : ð_dev->data->mac_addrs[0], hw->hash_search_index, 0, 0);
1319 [ # # ]: 0 : if (ret) {
1320 : 0 : PMD_DRV_LOG(ERR, "Failed to add mac: port 0x%x", hw->vport.vport);
1321 : 0 : return ret;
1322 : : }
1323 : 0 : hw->uc_num++;
1324 : : } else {
1325 : : struct zxdh_mac_filter *mac_filter = &msg_info.data.mac_filter_msg;
1326 : 0 : mac_filter->filter_flag = 0xff;
1327 : 0 : mac_filter->mac = eth_dev->data->mac_addrs[0];
1328 : 0 : zxdh_msg_head_build(hw, ZXDH_MAC_ADD, &msg_info);
1329 : 0 : ret = zxdh_vf_send_msg_to_pf(eth_dev, &msg_info, sizeof(msg_info), NULL, 0);
1330 [ # # ]: 0 : if (ret) {
1331 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: msg type %d", ZXDH_MAC_ADD);
1332 : 0 : return ret;
1333 : : }
1334 : 0 : hw->uc_num++;
1335 : : }
1336 : : return ret;
1337 : : }
1338 : :
1339 : 0 : static int32_t zxdh_reconfig_queues(struct rte_eth_dev *dev)
1340 : : {
1341 : : int32_t ret;
1342 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1343 : :
1344 : 0 : zxdh_pci_reset(hw);
1345 : :
1346 : : /* Tell the host we've noticed this device. */
1347 : 0 : zxdh_pci_set_status(hw, ZXDH_CONFIG_STATUS_ACK);
1348 : :
1349 : : /* Tell the host we've known how to drive the device. */
1350 : 0 : zxdh_pci_set_status(hw, ZXDH_CONFIG_STATUS_DRIVER);
1351 : : /* The queue needs to be released when reconfiguring */
1352 [ # # ]: 0 : if (hw->vqs != NULL) {
1353 : 0 : zxdh_dev_free_mbufs(dev);
1354 : 0 : zxdh_free_queues(dev);
1355 : : }
1356 : :
1357 : 0 : hw->rx_qnum = dev->data->nb_rx_queues;
1358 : 0 : hw->tx_qnum = dev->data->nb_tx_queues;
1359 : 0 : ret = zxdh_alloc_queues(dev);
1360 [ # # ]: 0 : if (ret < 0)
1361 : : return ret;
1362 : :
1363 [ # # ]: 0 : if (zxdh_configure_intr(dev) < 0) {
1364 : 0 : PMD_DRV_LOG(ERR, "Failed to configure interrupt");
1365 : 0 : zxdh_free_queues(dev);
1366 : 0 : return -1;
1367 : : }
1368 : :
1369 : 0 : zxdh_pci_reinit_complete(hw);
1370 : 0 : return 0;
1371 : : }
1372 : :
1373 : 0 : static int32_t zxdh_config_queue(struct rte_eth_dev *dev)
1374 : : {
1375 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1376 : : int32_t ret = 0, i = 0;
1377 : :
1378 [ # # ]: 0 : if (hw->queue_conf->queue_changed) {
1379 : 0 : ret = zxdh_reconfig_queues(dev);
1380 [ # # ]: 0 : if (ret)
1381 : : return ret;
1382 : :
1383 : 0 : ret = zxdh_rss_qid_config(dev);
1384 [ # # ]: 0 : if (ret) {
1385 : 0 : PMD_DRV_LOG(ERR, "Failed to configure base qid!");
1386 : 0 : return -1;
1387 : : }
1388 : :
1389 : 0 : ret = zxdh_rss_configure(dev);
1390 [ # # ]: 0 : if (ret) {
1391 : 0 : PMD_DRV_LOG(ERR, "Failed to config rss");
1392 : 0 : return -1;
1393 : : }
1394 : 0 : hw->queue_conf->queue_changed = 0;
1395 : : }
1396 : :
1397 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
1398 : 0 : ret = zxdh_tx_queue_config(dev, i);
1399 [ # # ]: 0 : if (ret) {
1400 : 0 : PMD_DRV_LOG(ERR, "Failed to config tx queue");
1401 : 0 : return ret;
1402 : : }
1403 : : }
1404 : :
1405 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
1406 : 0 : ret = zxdh_rx_queue_config(dev, i);
1407 [ # # ]: 0 : if (ret) {
1408 : 0 : PMD_DRV_LOG(ERR, "Failed to config rx queue");
1409 : 0 : return ret;
1410 : : }
1411 : 0 : ret = zxdh_dev_rx_queue_setup_finish(dev, i);
1412 [ # # ]: 0 : if (ret < 0)
1413 : 0 : return ret;
1414 : : }
1415 : :
1416 : : return 0;
1417 : : }
1418 : :
1419 : : static int
1420 : 0 : zxdh_dev_start(struct rte_eth_dev *dev)
1421 : : {
1422 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1423 : : struct zxdh_virtqueue *vq;
1424 : : int32_t ret;
1425 : : uint16_t logic_qidx;
1426 : : uint16_t i;
1427 : :
1428 : 0 : ret = zxdh_config_queue(dev);
1429 [ # # ]: 0 : if (ret)
1430 : : return ret;
1431 : :
1432 : 0 : zxdh_set_rxtx_funcs(dev);
1433 : 0 : ret = zxdh_intr_enable(dev);
1434 [ # # ]: 0 : if (ret) {
1435 : 0 : PMD_DRV_LOG(ERR, "interrupt enable failed");
1436 : 0 : return -EINVAL;
1437 : : }
1438 : :
1439 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
1440 : 0 : logic_qidx = 2 * i + ZXDH_RQ_QUEUE_IDX;
1441 : 0 : vq = hw->vqs[logic_qidx];
1442 : : /* Flush the old packets */
1443 : 0 : zxdh_queue_rxvq_flush(vq);
1444 : : zxdh_queue_notify(vq);
1445 : : }
1446 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
1447 : 0 : logic_qidx = 2 * i + ZXDH_TQ_QUEUE_IDX;
1448 : 0 : vq = hw->vqs[logic_qidx];
1449 : : zxdh_queue_notify(vq);
1450 : : }
1451 : :
1452 [ # # ]: 0 : if (hw->is_pf)
1453 : 0 : zxdh_link_speed_set(dev);
1454 : 0 : zxdh_autoneg_stats_get(dev);
1455 : :
1456 : 0 : hw->admin_status = RTE_ETH_LINK_UP;
1457 : 0 : zxdh_dev_link_update(dev, 0);
1458 : :
1459 : 0 : ret = zxdh_mac_config(hw->eth_dev);
1460 [ # # ]: 0 : if (ret)
1461 : 0 : PMD_DRV_LOG(ERR, "mac config failed");
1462 : :
1463 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++)
1464 : 0 : dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
1465 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++)
1466 : 0 : dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
1467 : :
1468 : : return 0;
1469 : : }
1470 : :
1471 : : static void
1472 : 0 : zxdh_rxq_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id, struct rte_eth_rxq_info *qinfo)
1473 : : {
1474 : : struct zxdh_virtnet_rx *rxq = NULL;
1475 : :
1476 [ # # ]: 0 : if (rx_queue_id < dev->data->nb_rx_queues)
1477 : 0 : rxq = dev->data->rx_queues[rx_queue_id];
1478 [ # # ]: 0 : if (!rxq) {
1479 : 0 : PMD_RX_LOG(ERR, "rxq is null");
1480 : 0 : return;
1481 : : }
1482 : 0 : qinfo->nb_desc = rxq->vq->vq_nentries;
1483 : 0 : qinfo->conf.rx_free_thresh = rxq->vq->vq_free_thresh;
1484 : 0 : qinfo->conf.offloads = dev->data->dev_conf.rxmode.offloads;
1485 : 0 : qinfo->queue_state = dev->data->rx_queue_state[rx_queue_id];
1486 : : }
1487 : :
1488 : : static void
1489 : 0 : zxdh_txq_info_get(struct rte_eth_dev *dev, uint16_t tx_queue_id, struct rte_eth_txq_info *qinfo)
1490 : : {
1491 : : struct zxdh_virtnet_tx *txq = NULL;
1492 : :
1493 [ # # ]: 0 : if (tx_queue_id < dev->data->nb_tx_queues)
1494 : 0 : txq = dev->data->tx_queues[tx_queue_id];
1495 [ # # ]: 0 : if (!txq) {
1496 : 0 : PMD_TX_LOG(ERR, "txq is null");
1497 : 0 : return;
1498 : : }
1499 : 0 : qinfo->nb_desc = txq->vq->vq_nentries;
1500 : 0 : qinfo->conf.tx_free_thresh = txq->vq->vq_free_thresh;
1501 : 0 : qinfo->conf.offloads = dev->data->dev_conf.txmode.offloads;
1502 : 0 : qinfo->queue_state = dev->data->tx_queue_state[tx_queue_id];
1503 : : }
1504 : :
1505 : : static const uint32_t *
1506 : 0 : zxdh_dev_supported_ptypes_get(struct rte_eth_dev *dev, size_t *ptype_sz)
1507 : : {
1508 : : static const uint32_t ptypes[] = {
1509 : : RTE_PTYPE_L2_ETHER,
1510 : : RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
1511 : : RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
1512 : : RTE_PTYPE_L4_NONFRAG,
1513 : : RTE_PTYPE_L4_FRAG,
1514 : : RTE_PTYPE_L4_TCP,
1515 : : RTE_PTYPE_L4_UDP,
1516 : : RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
1517 : : RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
1518 : : RTE_PTYPE_INNER_L4_NONFRAG,
1519 : : RTE_PTYPE_INNER_L4_FRAG,
1520 : : RTE_PTYPE_INNER_L4_TCP,
1521 : : RTE_PTYPE_INNER_L4_UDP,
1522 : : RTE_PTYPE_UNKNOWN
1523 : : };
1524 : :
1525 [ # # ]: 0 : if (!dev->rx_pkt_burst)
1526 : : return NULL;
1527 : 0 : *ptype_sz = sizeof(ptypes);
1528 : 0 : return ptypes;
1529 : : }
1530 : :
1531 : : /* dev_ops for zxdh, bare necessities for basic operation */
1532 : : static const struct eth_dev_ops zxdh_eth_dev_ops = {
1533 : : .dev_configure = zxdh_dev_configure,
1534 : : .dev_start = zxdh_dev_start,
1535 : : .dev_stop = zxdh_dev_stop,
1536 : : .dev_close = zxdh_dev_close,
1537 : : .dev_infos_get = zxdh_dev_infos_get,
1538 : : .rx_queue_setup = zxdh_dev_rx_queue_setup,
1539 : : .tx_queue_setup = zxdh_dev_tx_queue_setup,
1540 : : .rx_queue_intr_enable = zxdh_dev_rx_queue_intr_enable,
1541 : : .rx_queue_intr_disable = zxdh_dev_rx_queue_intr_disable,
1542 : : .rxq_info_get = zxdh_rxq_info_get,
1543 : : .txq_info_get = zxdh_txq_info_get,
1544 : : .link_update = zxdh_dev_link_update,
1545 : : .dev_set_link_up = zxdh_dev_set_link_up,
1546 : : .dev_set_link_down = zxdh_dev_set_link_down,
1547 : : .mac_addr_add = zxdh_dev_mac_addr_add,
1548 : : .mac_addr_remove = zxdh_dev_mac_addr_remove,
1549 : : .mac_addr_set = zxdh_dev_mac_addr_set,
1550 : : .promiscuous_enable = zxdh_dev_promiscuous_enable,
1551 : : .promiscuous_disable = zxdh_dev_promiscuous_disable,
1552 : : .allmulticast_enable = zxdh_dev_allmulticast_enable,
1553 : : .allmulticast_disable = zxdh_dev_allmulticast_disable,
1554 : : .vlan_tpid_set = zxdh_vlan_tpid_set,
1555 : : .vlan_filter_set = zxdh_dev_vlan_filter_set,
1556 : : .vlan_offload_set = zxdh_dev_vlan_offload_set,
1557 : : .reta_update = zxdh_dev_rss_reta_update,
1558 : : .reta_query = zxdh_dev_rss_reta_query,
1559 : : .rss_hash_update = zxdh_rss_hash_update,
1560 : : .rss_hash_conf_get = zxdh_rss_hash_conf_get,
1561 : : .stats_get = zxdh_dev_stats_get,
1562 : : .stats_reset = zxdh_dev_stats_reset,
1563 : : .xstats_get = zxdh_dev_xstats_get,
1564 : : .xstats_get_names = zxdh_dev_xstats_get_names,
1565 : : .xstats_reset = zxdh_dev_stats_reset,
1566 : : .mtu_set = zxdh_dev_mtu_set,
1567 : : .fw_version_get = zxdh_dev_fw_version_get,
1568 : : .get_module_info = zxdh_dev_get_module_info,
1569 : : .get_module_eeprom = zxdh_dev_get_module_eeprom,
1570 : : .dev_supported_ptypes_get = zxdh_dev_supported_ptypes_get,
1571 : : .mtr_ops_get = zxdh_meter_ops_get,
1572 : : .flow_ops_get = zxdh_flow_ops_get,
1573 : : };
1574 : :
1575 : : const struct eth_dev_ops zxdh_eth_dev_secondary_ops = {
1576 : : .dev_infos_get = zxdh_dev_infos_get,
1577 : : .stats_get = zxdh_dev_stats_get,
1578 : : .xstats_get = zxdh_dev_xstats_get,
1579 : : .xstats_get_names = zxdh_dev_xstats_get_names,
1580 : : .rxq_info_get = zxdh_rxq_info_get,
1581 : : .txq_info_get = zxdh_txq_info_get,
1582 : : .dev_supported_ptypes_get = zxdh_dev_supported_ptypes_get,
1583 : : };
1584 : :
1585 : : static int32_t
1586 : 0 : zxdh_init_device(struct rte_eth_dev *eth_dev)
1587 : : {
1588 : 0 : struct zxdh_hw *hw = eth_dev->data->dev_private;
1589 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
1590 : : int ret = 0;
1591 : :
1592 : 0 : ret = zxdh_read_pci_caps(pci_dev, hw);
1593 [ # # ]: 0 : if (ret) {
1594 : 0 : PMD_DRV_LOG(ERR, "port 0x%x pci caps read failed", hw->port_id);
1595 : 0 : goto err;
1596 : : }
1597 : :
1598 : 0 : zxdh_hw_internal[hw->port_id].zxdh_vtpci_ops = &zxdh_dev_pci_ops;
1599 : 0 : zxdh_pci_reset(hw);
1600 : 0 : zxdh_get_pci_dev_config(hw);
1601 : :
1602 [ # # ]: 0 : rte_ether_addr_copy((struct rte_ether_addr *)hw->mac_addr, ð_dev->data->mac_addrs[0]);
1603 : :
1604 : : /* If host does not support both status and MSI-X then disable LSC */
1605 [ # # # # ]: 0 : if (zxdh_pci_with_feature(hw, ZXDH_NET_F_STATUS) && hw->use_msix != ZXDH_MSIX_NONE)
1606 : 0 : eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
1607 : : else
1608 : 0 : eth_dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
1609 : :
1610 : : return 0;
1611 : :
1612 : : err:
1613 : 0 : PMD_DRV_LOG(ERR, "port %d init device failed", eth_dev->data->port_id);
1614 : 0 : return ret;
1615 : : }
1616 : :
1617 : : static int
1618 : 0 : zxdh_agent_comm(struct rte_eth_dev *eth_dev, struct zxdh_hw *hw)
1619 : : {
1620 [ # # ]: 0 : if (zxdh_phyport_get(eth_dev, &hw->phyport) != 0) {
1621 : 0 : PMD_DRV_LOG(ERR, "Failed to get phyport");
1622 : 0 : return -1;
1623 : : }
1624 : 0 : PMD_DRV_LOG(DEBUG, "Get phyport success: 0x%x", hw->phyport);
1625 : :
1626 : 0 : hw->vfid = zxdh_vport_to_vfid(hw->vport);
1627 : :
1628 [ # # ]: 0 : if (zxdh_hashidx_get(eth_dev, &hw->hash_search_index) != 0) {
1629 : 0 : PMD_DRV_LOG(ERR, "Failed to get hash idx");
1630 : 0 : return -1;
1631 : : }
1632 : :
1633 [ # # ]: 0 : if (zxdh_panelid_get(eth_dev, &hw->panel_id) != 0) {
1634 : 0 : PMD_DRV_LOG(ERR, "Failed to get panel_id");
1635 : 0 : return -1;
1636 : : }
1637 : :
1638 : 0 : zxdh_speed_modes_get(eth_dev);
1639 : :
1640 [ # # ]: 0 : if (hw->switchoffload)
1641 : 0 : hw->phyport = 9;
1642 : :
1643 : 0 : PMD_DRV_LOG(DEBUG, "Get panel id success: 0x%x", hw->panel_id);
1644 : :
1645 : 0 : return 0;
1646 : : }
1647 : :
1648 : : static inline int
1649 : 0 : zxdh_dtb_dump_res_init(struct zxdh_hw *hw, ZXDH_DEV_INIT_CTRL_T *dpp_ctrl)
1650 : : {
1651 : : int ret = 0, i;
1652 : :
1653 : 0 : struct zxdh_dtb_bulk_dump_info dtb_dump_baseres[] = {
1654 : : {"sdt_vport_att_table", 4 * 1024 * 1024, ZXDH_SDT_VPORT_ATT_TABLE, NULL},
1655 : : {"sdt_vlan_att_table", 4 * 1024 * 1024, ZXDH_SDT_VLAN_ATT_TABLE, NULL},
1656 : : {"sdt_rss_table", 4 * 1024 * 1024, ZXDH_SDT_RSS_ATT_TABLE, NULL},
1657 : : {"sdt_l2_entry_table0", 5 * 1024 * 1024, ZXDH_SDT_L2_ENTRY_TABLE0, NULL},
1658 : : {"sdt_l2_entry_table1", 5 * 1024 * 1024, ZXDH_SDT_L2_ENTRY_TABLE1, NULL},
1659 : : {"sdt_l2_entry_table2", 5 * 1024 * 1024, ZXDH_SDT_L2_ENTRY_TABLE2, NULL},
1660 : : {"sdt_l2_entry_table3", 5 * 1024 * 1024, ZXDH_SDT_L2_ENTRY_TABLE3, NULL},
1661 : : {"sdt_mc_table0", 5 * 1024 * 1024, ZXDH_SDT_MC_TABLE0, NULL},
1662 : : {"sdt_mc_table1", 5 * 1024 * 1024, ZXDH_SDT_MC_TABLE1, NULL},
1663 : : {"sdt_mc_table2", 5 * 1024 * 1024, ZXDH_SDT_MC_TABLE2, NULL},
1664 : : {"sdt_mc_table3", 5 * 1024 * 1024, ZXDH_SDT_MC_TABLE3, NULL},
1665 : : {"sdt_acl_index_mng", 4 * 1024 * 1024, 30, NULL},
1666 : : {"sdt_fd_table", 4 * 1024 * 1024, ZXDH_SDT_FD_TABLE, NULL},
1667 : : };
1668 : :
1669 : 0 : struct zxdh_dev_shared_data *dev_sd = hw->dev_sd;
1670 : : struct zxdh_dtb_shared_data *dtb_data = &dev_sd->dtb_sd;
1671 : :
1672 [ # # ]: 0 : for (i = 0; i < (int)RTE_DIM(dtb_dump_baseres); i++) {
1673 : 0 : struct zxdh_dtb_bulk_dump_info *p = dtb_dump_baseres + i;
1674 : 0 : char buf[ZXDH_MAX_NAME_LEN] = {0};
1675 : 0 : snprintf(buf, sizeof(buf), "%s_%x", p->mz_name, hw->dev_id);
1676 : 0 : p->mz_name = buf;
1677 : :
1678 : : const struct rte_memzone *generic_dump_mz =
1679 : 0 : rte_memzone_reserve_aligned(p->mz_name, p->mz_size,
1680 : : SOCKET_ID_ANY, 0, RTE_CACHE_LINE_SIZE);
1681 [ # # ]: 0 : if (generic_dump_mz == NULL) {
1682 : 0 : PMD_DRV_LOG(ERR, "Cannot alloc mem for dtb table bulk dump, mz_name is %s, mz_size is %u",
1683 : : p->mz_name, p->mz_size);
1684 : : ret = -ENOMEM;
1685 : 0 : return ret;
1686 : : }
1687 : 0 : p->mz = generic_dump_mz;
1688 : 0 : dpp_ctrl->dump_addr_info[i].vir_addr = generic_dump_mz->addr_64;
1689 : 0 : dpp_ctrl->dump_addr_info[i].phy_addr = generic_dump_mz->iova;
1690 : 0 : dpp_ctrl->dump_addr_info[i].sdt_no = p->sdt_no;
1691 : 0 : dpp_ctrl->dump_addr_info[i].size = p->mz_size;
1692 : :
1693 : 0 : dtb_data->dtb_table_bulk_dump_mz[dpp_ctrl->dump_sdt_num] = generic_dump_mz;
1694 : 0 : dpp_ctrl->dump_sdt_num++;
1695 : : }
1696 : : return ret;
1697 : : }
1698 : :
1699 : : static int
1700 : 0 : zxdh_np_dtb_res_init(struct rte_eth_dev *dev)
1701 : : {
1702 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1703 : 0 : struct zxdh_bar_offset_params param = {0};
1704 : 0 : struct zxdh_bar_offset_res res = {0};
1705 : 0 : char buf[ZXDH_MAX_NAME_LEN] = {0};
1706 : 0 : struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;
1707 : 0 : struct zxdh_dev_nic_shared_data *dev_nic_sd = hw->dev_nic_sd;
1708 : : int ret = 0;
1709 : :
1710 [ # # ]: 0 : if (dtb_data->init_done) {
1711 : 0 : PMD_DRV_LOG(DEBUG, "DTB res already init done, dev %s no need init",
1712 : : dev->device->name);
1713 : 0 : return 0;
1714 : : }
1715 : :
1716 : 0 : dtb_data->queueid = ZXDH_INVALID_DTBQUE;
1717 : 0 : dtb_data->bind_device = dev;
1718 : :
1719 : 0 : ZXDH_DEV_INIT_CTRL_T *dpp_ctrl = rte_zmalloc(NULL, sizeof(*dpp_ctrl) +
1720 : : sizeof(ZXDH_DTB_ADDR_INFO_T) * 256, 0);
1721 [ # # ]: 0 : if (dpp_ctrl == NULL) {
1722 : 0 : PMD_DRV_LOG(ERR, "dev %s annot allocate memory for dpp_ctrl", dev->device->name);
1723 : : ret = -ENOMEM;
1724 : 0 : return ret;
1725 : : }
1726 : 0 : dpp_ctrl->queue_id = 0xff;
1727 : 0 : dpp_ctrl->vport = hw->vport.vport;
1728 : 0 : dpp_ctrl->vector = ZXDH_MSIX_INTR_DTB_VEC;
1729 : 0 : strlcpy(dpp_ctrl->port_name, dev->device->name, sizeof(dpp_ctrl->port_name));
1730 : 0 : dpp_ctrl->pcie_vir_addr = hw->bar_addr[0];
1731 : :
1732 : 0 : param.pcie_id = hw->pcie_id;
1733 : 0 : param.virt_addr = hw->bar_addr[0] + ZXDH_CTRLCH_OFFSET;
1734 : 0 : param.type = ZXDH_URI_NP;
1735 : :
1736 : 0 : ret = zxdh_get_bar_offset(¶m, &res);
1737 [ # # ]: 0 : if (ret) {
1738 : 0 : PMD_DRV_LOG(ERR, "dev %s get npbar offset failed", dev->device->name);
1739 : 0 : goto free_res;
1740 : : }
1741 : 0 : dpp_ctrl->np_bar_len = res.bar_length;
1742 : 0 : dpp_ctrl->np_bar_offset = res.bar_offset;
1743 : :
1744 [ # # ]: 0 : if (!dtb_data->dtb_table_conf_mz) {
1745 : 0 : snprintf(buf, sizeof(buf), "%s_%x", "zxdh_dtb_table_conf_mz", hw->dev_id);
1746 : 0 : const struct rte_memzone *conf_mz = rte_memzone_reserve_aligned(buf,
1747 : : ZXDH_DTB_TABLE_CONF_SIZE, SOCKET_ID_ANY, 0, RTE_CACHE_LINE_SIZE);
1748 : :
1749 [ # # ]: 0 : if (conf_mz == NULL) {
1750 : 0 : PMD_DRV_LOG(ERR,
1751 : : "dev %s annot allocate memory for dtb table conf",
1752 : : dev->device->name);
1753 : : ret = -ENOMEM;
1754 : 0 : goto free_res;
1755 : : }
1756 : 0 : dpp_ctrl->down_vir_addr = conf_mz->addr_64;
1757 : 0 : dpp_ctrl->down_phy_addr = conf_mz->iova;
1758 : 0 : dtb_data->dtb_table_conf_mz = conf_mz;
1759 : : }
1760 : :
1761 [ # # ]: 0 : if (!dtb_data->dtb_table_dump_mz) {
1762 : : memset(buf, '\0', sizeof(buf));
1763 : 0 : snprintf(buf, sizeof(buf), "%s_%x", "zxdh_dtb_table_dump_mz", hw->dev_id);
1764 : 0 : const struct rte_memzone *dump_mz = rte_memzone_reserve_aligned(buf,
1765 : : ZXDH_DTB_TABLE_DUMP_SIZE, SOCKET_ID_ANY, 0, RTE_CACHE_LINE_SIZE);
1766 : :
1767 [ # # ]: 0 : if (dump_mz == NULL) {
1768 : 0 : PMD_DRV_LOG(ERR,
1769 : : "dev %s Cannot allocate memory for dtb table dump",
1770 : : dev->device->name);
1771 : : ret = -ENOMEM;
1772 : 0 : goto free_res;
1773 : : }
1774 : 0 : dpp_ctrl->dump_vir_addr = dump_mz->addr_64;
1775 : 0 : dpp_ctrl->dump_phy_addr = dump_mz->iova;
1776 : 0 : dtb_data->dtb_table_dump_mz = dump_mz;
1777 : : }
1778 : :
1779 : 0 : ret = zxdh_dtb_dump_res_init(hw, dpp_ctrl);
1780 [ # # ]: 0 : if (ret) {
1781 : 0 : PMD_DRV_LOG(ERR, "dev %s zxdh_dtb_dump_res_init failed", dev->device->name);
1782 : 0 : goto free_res;
1783 : : }
1784 : :
1785 : 0 : ret = zxdh_np_host_init(hw->dev_id, dpp_ctrl);
1786 [ # # ]: 0 : if (ret) {
1787 : 0 : PMD_DRV_LOG(ERR, "dev %s dpp host np init failed", dev->device->name);
1788 : 0 : goto free_res;
1789 : : }
1790 : :
1791 : 0 : PMD_DRV_LOG(DEBUG, "dev %s dpp host np init ok.dtb queue %u",
1792 : : dev->device->name, dpp_ctrl->queue_id);
1793 : 0 : dtb_data->queueid = dpp_ctrl->queue_id;
1794 : 0 : dtb_data->dev_refcnt++;
1795 : 0 : dev_nic_sd->dtb_used_num++;
1796 : 0 : dtb_data->init_done = 1;
1797 : 0 : rte_free(dpp_ctrl);
1798 : 0 : return 0;
1799 : :
1800 : 0 : free_res:
1801 : 0 : zxdh_np_dtb_data_res_free(hw);
1802 : 0 : rte_free(dpp_ctrl);
1803 : 0 : return ret;
1804 : : }
1805 : :
1806 : : static inline uint16_t
1807 : 0 : zxdh_get_dev_shared_data_idx(uint32_t dev_serial_id)
1808 : : {
1809 : : uint16_t idx = 0;
1810 [ # # ]: 0 : for (; idx < ZXDH_SLOT_MAX; idx++) {
1811 [ # # # # ]: 0 : if (dev_nic_sd[idx].serial_id == dev_serial_id || dev_nic_sd[idx].serial_id == 0)
1812 : 0 : return idx;
1813 : : }
1814 : :
1815 : 0 : PMD_DRV_LOG(ERR, "dev serial_id[%u] can not found in global dev_nic_share_data arrays",
1816 : : dev_serial_id);
1817 : 0 : return ZXDH_INVALID_SLOT_IDX;
1818 : : }
1819 : :
1820 : 0 : static int zxdh_init_dev_share_data(struct rte_eth_dev *eth_dev)
1821 : : {
1822 : 0 : struct zxdh_hw *hw = eth_dev->data->dev_private;
1823 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
1824 : 0 : uint32_t serial_id = (pci_dev->addr.domain << 16) |
1825 : 0 : (pci_dev->addr.bus << 8) | pci_dev->addr.devid;
1826 : : uint16_t slot_id = 0;
1827 : :
1828 [ # # ]: 0 : if (serial_id <= 0) {
1829 : 0 : PMD_DRV_LOG(ERR, "failed to get pcie bus-info %s", pci_dev->name);
1830 : 0 : return -EINVAL;
1831 : : }
1832 : :
1833 : 0 : slot_id = zxdh_get_dev_shared_data_idx(serial_id);
1834 [ # # ]: 0 : if (slot_id == ZXDH_INVALID_SLOT_IDX)
1835 : : return -EINVAL;
1836 : :
1837 : 0 : hw->slot_id = slot_id;
1838 : 0 : hw->dev_id = hw->pcie_id;
1839 : 0 : dev_nic_sd[slot_id].serial_id = serial_id;
1840 : 0 : hw->dev_nic_sd = &dev_nic_sd[slot_id];
1841 : 0 : hw->dev_sd = rte_zmalloc("zxdh_dtb", sizeof(struct zxdh_dev_shared_data), 0);
1842 : :
1843 : 0 : return 0;
1844 : : }
1845 : :
1846 : : static int
1847 : 0 : zxdh_init_shared_data(void)
1848 : : {
1849 : : const struct rte_memzone *mz;
1850 : : int ret = 0;
1851 : :
1852 : : rte_spinlock_lock(&zxdh_shared_data_lock);
1853 [ # # ]: 0 : if (zxdh_shared_data == NULL) {
1854 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
1855 : : /* Allocate shared memory. */
1856 : 0 : mz = rte_memzone_reserve("zxdh_pmd_shared_data",
1857 : : sizeof(*zxdh_shared_data), SOCKET_ID_ANY, 0);
1858 [ # # ]: 0 : if (mz == NULL) {
1859 : 0 : PMD_DRV_LOG(ERR, "Cannot allocate zxdh shared data");
1860 : 0 : ret = -rte_errno;
1861 : 0 : goto error;
1862 : : }
1863 : 0 : zxdh_shared_data = mz->addr;
1864 : : memset(zxdh_shared_data, 0, sizeof(*zxdh_shared_data));
1865 : 0 : rte_spinlock_init(&zxdh_shared_data->lock);
1866 : : } else { /* Lookup allocated shared memory. */
1867 : 0 : mz = rte_memzone_lookup("zxdh_pmd_shared_data");
1868 [ # # ]: 0 : if (mz == NULL) {
1869 : 0 : PMD_DRV_LOG(ERR, "Cannot attach zxdh shared data");
1870 : 0 : ret = -rte_errno;
1871 : 0 : goto error;
1872 : : }
1873 : 0 : zxdh_shared_data = mz->addr;
1874 : : }
1875 : : }
1876 : :
1877 : 0 : error:
1878 : : rte_spinlock_unlock(&zxdh_shared_data_lock);
1879 : 0 : return ret;
1880 : : }
1881 : :
1882 : : static void
1883 : 0 : zxdh_free_sh_res(void)
1884 : : {
1885 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
1886 : : rte_spinlock_lock(&zxdh_shared_data_lock);
1887 [ # # # # ]: 0 : if (zxdh_shared_data != NULL && zxdh_shared_data->init_done &&
1888 [ # # ]: 0 : (--zxdh_shared_data->dev_refcnt == 0)) {
1889 : 0 : rte_mempool_free(zxdh_shared_data->flow_mp);
1890 : 0 : rte_mempool_free(zxdh_shared_data->mtr_mp);
1891 : 0 : rte_mempool_free(zxdh_shared_data->mtr_profile_mp);
1892 : 0 : rte_mempool_free(zxdh_shared_data->mtr_policy_mp);
1893 : : }
1894 : : rte_spinlock_unlock(&zxdh_shared_data_lock);
1895 : : }
1896 : 0 : }
1897 : :
1898 : : static int
1899 : 0 : zxdh_init_sh_res(struct zxdh_shared_data *sd)
1900 : : {
1901 : : const char *MZ_ZXDH_FLOW_MP = "zxdh_flow_mempool";
1902 : : const char *MZ_ZXDH_MTR_MP = "zxdh_mtr_mempool";
1903 : : const char *MZ_ZXDH_MTR_PROFILE_MP = "zxdh_mtr_profile_mempool";
1904 : : const char *MZ_ZXDH_MTR_POLICY_MP = "zxdh_mtr_policy_mempool";
1905 : : struct rte_mempool *flow_mp = NULL;
1906 : : struct rte_mempool *mtr_mp = NULL;
1907 : : struct rte_mempool *mtr_profile_mp = NULL;
1908 : : struct rte_mempool *mtr_policy_mp = NULL;
1909 : :
1910 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
1911 : 0 : flow_mp = rte_mempool_create(MZ_ZXDH_FLOW_MP, ZXDH_MAX_FLOW_NUM,
1912 : : sizeof(struct zxdh_flow), 64, 0,
1913 : : NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);
1914 [ # # ]: 0 : if (flow_mp == NULL) {
1915 : 0 : PMD_DRV_LOG(ERR, "Cannot allocate zxdh flow mempool");
1916 : 0 : goto error;
1917 : : }
1918 : 0 : mtr_mp = rte_mempool_create(MZ_ZXDH_MTR_MP, ZXDH_MAX_MTR_NUM,
1919 : : sizeof(struct zxdh_mtr_object), 64, 0,
1920 : : NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);
1921 [ # # ]: 0 : if (mtr_mp == NULL) {
1922 : 0 : PMD_DRV_LOG(ERR, "Cannot allocate zxdh mtr mempool");
1923 : 0 : goto error;
1924 : : }
1925 : 0 : mtr_profile_mp = rte_mempool_create(MZ_ZXDH_MTR_PROFILE_MP,
1926 : : MAX_MTR_PROFILE_NUM, sizeof(struct zxdh_meter_profile),
1927 : : 64, 0, NULL, NULL, NULL,
1928 : : NULL, SOCKET_ID_ANY, 0);
1929 [ # # ]: 0 : if (mtr_profile_mp == NULL) {
1930 : 0 : PMD_DRV_LOG(ERR, "Cannot allocate zxdh mtr profile mempool");
1931 : 0 : goto error;
1932 : : }
1933 : 0 : mtr_policy_mp = rte_mempool_create(MZ_ZXDH_MTR_POLICY_MP,
1934 : : ZXDH_MAX_POLICY_NUM, sizeof(struct zxdh_meter_policy),
1935 : : 64, 0, NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);
1936 [ # # ]: 0 : if (mtr_policy_mp == NULL) {
1937 : 0 : PMD_DRV_LOG(ERR, "Cannot allocate zxdh mtr profile mempool");
1938 : 0 : goto error;
1939 : : }
1940 : 0 : sd->flow_mp = flow_mp;
1941 : 0 : sd->mtr_mp = mtr_mp;
1942 : 0 : sd->mtr_profile_mp = mtr_profile_mp;
1943 : 0 : sd->mtr_policy_mp = mtr_policy_mp;
1944 : 0 : TAILQ_INIT(&zxdh_shared_data->meter_profile_list);
1945 : 0 : TAILQ_INIT(&zxdh_shared_data->mtr_list);
1946 : 0 : TAILQ_INIT(&zxdh_shared_data->mtr_policy_list);
1947 : : }
1948 : : return 0;
1949 : :
1950 : 0 : error:
1951 : 0 : rte_mempool_free(mtr_policy_mp);
1952 : 0 : rte_mempool_free(mtr_profile_mp);
1953 : 0 : rte_mempool_free(mtr_mp);
1954 : 0 : rte_mempool_free(flow_mp);
1955 : 0 : return -rte_errno;
1956 : : }
1957 : :
1958 : : static int
1959 : 0 : zxdh_init_once(struct rte_eth_dev *eth_dev)
1960 : : {
1961 : 0 : struct zxdh_hw *hw = eth_dev->data->dev_private;
1962 : : int ret = 0;
1963 : :
1964 [ # # ]: 0 : if (hw->is_pf) {
1965 : 0 : ret = zxdh_init_dev_share_data(eth_dev);
1966 [ # # ]: 0 : if (ret < 0) {
1967 : 0 : PMD_DRV_LOG(ERR, "init dev share date failed");
1968 : 0 : return ret;
1969 : : }
1970 : : }
1971 : :
1972 [ # # ]: 0 : if (zxdh_init_shared_data())
1973 : : return -1;
1974 : :
1975 : 0 : struct zxdh_shared_data *sd = zxdh_shared_data;
1976 : 0 : rte_spinlock_lock(&sd->lock);
1977 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
1978 [ # # ]: 0 : if (!sd->init_done) {
1979 : 0 : ++sd->secondary_cnt;
1980 : 0 : sd->init_done = true;
1981 : : }
1982 : 0 : goto out;
1983 : : }
1984 : : /* RTE_PROC_PRIMARY */
1985 [ # # ]: 0 : if (!sd->init_done) {
1986 : : /*shared struct and res init */
1987 : 0 : ret = zxdh_init_sh_res(sd);
1988 [ # # ]: 0 : if (ret != 0)
1989 : 0 : goto out;
1990 : 0 : zxdh_flow_global_init();
1991 : : rte_spinlock_init(&g_mtr_res.hw_plcr_res_lock);
1992 : : memset(&g_mtr_res, 0, sizeof(g_mtr_res));
1993 : 0 : sd->init_done = true;
1994 : : }
1995 : 0 : sd->dev_refcnt++;
1996 : 0 : out:
1997 : : rte_spinlock_unlock(&sd->lock);
1998 : 0 : return ret;
1999 : : }
2000 : :
2001 : : static int
2002 : 0 : zxdh_tbl_entry_offline_destroy(struct zxdh_hw *hw)
2003 : : {
2004 : 0 : struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;
2005 : : int ret = 0;
2006 [ # # ]: 0 : if (!dtb_data->init_done)
2007 : : return ret;
2008 [ # # ]: 0 : if (hw->is_pf) {
2009 : : uint32_t sdt_no;
2010 : 0 : sdt_no = ZXDH_SDT_L2_ENTRY_TABLE0 + hw->hash_search_index;
2011 : 0 : ret = zxdh_np_dtb_hash_offline_delete(hw->dev_id, dtb_data->queueid, sdt_no, 0);
2012 [ # # ]: 0 : if (ret)
2013 : 0 : PMD_DRV_LOG(ERR, "sdt_no %d delete failed. code:%d ", sdt_no, ret);
2014 : 0 : sdt_no = ZXDH_SDT_MC_TABLE0 + hw->hash_search_index;
2015 : 0 : ret = zxdh_np_dtb_hash_offline_delete(hw->dev_id, dtb_data->queueid, sdt_no, 0);
2016 [ # # ]: 0 : if (ret)
2017 : 0 : PMD_DRV_LOG(ERR, "sdt_no %d delete failed. code:%d ", sdt_no, ret);
2018 : :
2019 : 0 : ret = zxdh_np_dtb_acl_offline_delete(hw->dev_id, dtb_data->queueid,
2020 : 0 : ZXDH_SDT_FD_TABLE, hw->vport.vport,
2021 : : ZXDH_FLOW_STATS_INGRESS_BASE, 1);
2022 [ # # ]: 0 : if (ret)
2023 : 0 : PMD_DRV_LOG(ERR, "flow offline delete failed. code:%d", ret);
2024 : : }
2025 : : return ret;
2026 : : }
2027 : :
2028 : : static int
2029 : 0 : zxdh_np_init(struct rte_eth_dev *eth_dev)
2030 : : {
2031 : 0 : struct zxdh_hw *hw = eth_dev->data->dev_private;
2032 : 0 : struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;
2033 : 0 : struct zxdh_dev_nic_shared_data *dev_nic_sd = hw->dev_nic_sd;
2034 : : int ret = 0;
2035 : :
2036 [ # # ]: 0 : if (!hw->is_pf)
2037 : : return 0;
2038 : :
2039 : 0 : hw->dev_id = (hw->pcie_id << 16) | (hw->slot_id & 0xffff);
2040 : :
2041 : 0 : ret = zxdh_np_dtb_res_init(eth_dev);
2042 [ # # ]: 0 : if (ret) {
2043 : 0 : PMD_DRV_LOG(ERR, "np dtb init failed, ret:%d", ret);
2044 : 0 : return ret;
2045 : : }
2046 : :
2047 [ # # ]: 0 : if (dev_nic_sd->init_done) {
2048 : 0 : zxdh_tbl_entry_offline_destroy(hw);
2049 : 0 : PMD_DRV_LOG(ERR, "no need to init apt res. slot_id %d dtb chanenl %d dtb_used_num %d",
2050 : : hw->slot_id, dtb_data->queueid, hw->dev_nic_sd->dtb_used_num);
2051 : 0 : return 0;
2052 : : }
2053 : 0 : ret = zxdh_np_se_res_get_and_init(hw->dev_id, ZXDH_SE_STD_NIC_RES_TYPE);
2054 [ # # ]: 0 : if (ret) {
2055 : 0 : PMD_DRV_LOG(ERR, "dpp apt init failed, code:%d ", ret);
2056 : 0 : return -ret;
2057 : : }
2058 [ # # ]: 0 : if (!hw->switchoffload) {
2059 [ # # ]: 0 : if (hw->hash_search_index >= ZXDH_HASHIDX_MAX) {
2060 : 0 : PMD_DRV_LOG(ERR, "invalid hash idx %d", hw->hash_search_index);
2061 : 0 : return -1;
2062 : : }
2063 : 0 : zxdh_tbl_entry_offline_destroy(hw);
2064 : : }
2065 : 0 : dev_nic_sd->init_done = 1;
2066 : :
2067 : 0 : PMD_DRV_LOG(DEBUG, "np init ok");
2068 : 0 : return 0;
2069 : : }
2070 : :
2071 : : static int
2072 : 0 : zxdh_tables_init(struct rte_eth_dev *dev)
2073 : : {
2074 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
2075 : : int ret = 0;
2076 : :
2077 : 0 : ret = zxdh_port_attr_init(dev);
2078 [ # # ]: 0 : if (ret) {
2079 : 0 : PMD_DRV_LOG(ERR, "zxdh_port_attr_init failed");
2080 : 0 : return ret;
2081 : : }
2082 : :
2083 : 0 : ret = zxdh_panel_table_init(dev);
2084 [ # # ]: 0 : if (ret) {
2085 : 0 : PMD_DRV_LOG(ERR, "panel table init failed");
2086 : 0 : return ret;
2087 : : }
2088 : :
2089 : 0 : ret = zxdh_promisc_table_init(dev);
2090 [ # # ]: 0 : if (ret) {
2091 : 0 : PMD_DRV_LOG(ERR, "promisc_table_init failed");
2092 : 0 : return ret;
2093 : : }
2094 : :
2095 : 0 : ret = zxdh_vlan_filter_table_init(hw, hw->vport.vport);
2096 [ # # ]: 0 : if (ret) {
2097 : 0 : PMD_DRV_LOG(ERR, "vlan filter table init failed");
2098 : 0 : return ret;
2099 : : }
2100 : :
2101 : 0 : ret = zxdh_port_vlan_table_init(hw, hw->vport.vport);
2102 [ # # ]: 0 : if (ret) {
2103 : 0 : PMD_DRV_LOG(ERR, "port vlan table init failed");
2104 : 0 : return ret;
2105 : : }
2106 : :
2107 : : return ret;
2108 : : }
2109 : :
2110 : : static void
2111 : 0 : zxdh_queue_res_get(struct rte_eth_dev *eth_dev)
2112 : : {
2113 : 0 : struct zxdh_hw *hw = eth_dev->data->dev_private;
2114 : : uint32_t value = 0;
2115 : : uint16_t offset = 0;
2116 : :
2117 : 0 : offset = hw->vport.epid * 8 + hw->vport.pfid;
2118 [ # # ]: 0 : if (hw->is_pf) {
2119 : 0 : hw->max_queue_pairs = *(volatile uint8_t *)(hw->bar_addr[0] +
2120 : : ZXDH_PF_QUEUE_PAIRS_ADDR);
2121 : 0 : PMD_DRV_LOG(DEBUG, "is_pf max_queue_pairs is %x", hw->max_queue_pairs);
2122 : : } else {
2123 : 0 : hw->max_queue_pairs = *(volatile uint8_t *)(hw->bar_addr[0] +
2124 : 0 : ZXDH_VF_QUEUE_PAIRS_ADDR + offset);
2125 : 0 : PMD_DRV_LOG(DEBUG, "is_vf max_queue_pairs is %x", hw->max_queue_pairs);
2126 : : }
2127 : :
2128 : : /* pf/vf read queue start id and queue_max cfg */
2129 : 0 : value = *(volatile uint32_t *)(hw->bar_addr[0] + ZXDH_QUEUE_POOL_ADDR + offset * 4);
2130 : 0 : hw->queue_pool_count = value & 0x0000ffff;
2131 : 0 : hw->queue_pool_start = value >> 16;
2132 [ # # ]: 0 : if (hw->max_queue_pairs > ZXDH_RX_QUEUES_MAX || hw->max_queue_pairs == 0)
2133 : 0 : hw->max_queue_pairs = ZXDH_RX_QUEUES_MAX;
2134 [ # # ]: 0 : if (hw->queue_pool_count > ZXDH_TOTAL_QUEUES_NUM / 2 || hw->queue_pool_count == 0)
2135 : 0 : hw->queue_pool_count = ZXDH_TOTAL_QUEUES_NUM / 2;
2136 [ # # ]: 0 : if (hw->queue_pool_start > ZXDH_TOTAL_QUEUES_NUM / 2)
2137 : 0 : hw->queue_pool_start = 0;
2138 : 0 : }
2139 : :
2140 : : static int
2141 : 0 : zxdh_priv_res_init(struct zxdh_hw *hw)
2142 : : {
2143 [ # # ]: 0 : if (hw->is_pf) {
2144 : 0 : hw->vfinfo = rte_zmalloc("vfinfo", ZXDH_MAX_VF * sizeof(struct vfinfo), 4);
2145 [ # # ]: 0 : if (hw->vfinfo == NULL) {
2146 : 0 : PMD_DRV_LOG(ERR, "vfinfo malloc failed");
2147 : 0 : return -ENOMEM;
2148 : : }
2149 : : } else {
2150 : 0 : hw->vfinfo = NULL;
2151 : : }
2152 : :
2153 : 0 : hw->channel_context = rte_zmalloc("zxdh_chnlctx",
2154 : : sizeof(struct zxdh_chnl_context) * ZXDH_QUEUES_NUM_MAX, 0);
2155 [ # # ]: 0 : if (hw->channel_context == NULL) {
2156 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate channel_context");
2157 : 0 : return -ENOMEM;
2158 : : }
2159 : :
2160 : 0 : hw->queue_conf = rte_zmalloc("zxdh_queue_conf", sizeof(struct zxdh_queue_conf), 0);
2161 [ # # ]: 0 : if (hw->queue_conf == NULL) {
2162 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate queue conf");
2163 : 0 : return -ENOMEM;
2164 : : }
2165 : :
2166 : 0 : hw->net_hdr_dl = rte_zmalloc("zxdh_net_hdr_dl", sizeof(struct zxdh_net_hdr_dl), 0);
2167 [ # # ]: 0 : if (hw->net_hdr_dl == NULL) {
2168 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate %zu bytes store queue conf",
2169 : : sizeof(struct zxdh_net_hdr_dl));
2170 : 0 : return -ENOMEM;
2171 : : }
2172 : :
2173 : : return 0;
2174 : : }
2175 : :
2176 : :
2177 : : static uint8_t
2178 : 0 : is_pf(uint16_t device_id)
2179 : : {
2180 : 0 : return (device_id == ZXDH_E310_PF_DEVICEID ||
2181 [ # # # # : 0 : device_id == ZXDH_E312_PF_DEVICEID ||
# # ]
2182 : : device_id == ZXDH_E312S_PF_DEVICEID ||
2183 : : device_id == ZXDH_E316_PF_DEVICEID ||
2184 : : device_id == ZXDH_E310_RDMA_PF_DEVICEID ||
2185 : : device_id == ZXDH_E312_RDMA_PF_DEVICEID ||
2186 : : device_id == ZXDH_I510_OVS_PF_DEVICEID ||
2187 : : device_id == ZXDH_I510_BOND_PF_DEVICEID ||
2188 : 0 : device_id == ZXDH_I511_OVS_PF_DEVICEID ||
2189 : : device_id == ZXDH_I511_BOND_PF_DEVICEID);
2190 : : }
2191 : :
2192 : : static uint8_t
2193 : : is_inic_pf(uint16_t device_id)
2194 : : {
2195 : : return (device_id == ZXDH_I510_OVS_PF_DEVICEID ||
2196 : : device_id == ZXDH_I510_BOND_PF_DEVICEID ||
2197 : 0 : device_id == ZXDH_I511_OVS_PF_DEVICEID ||
2198 : : device_id == ZXDH_I511_BOND_PF_DEVICEID);
2199 : : }
2200 : :
2201 : : static int
2202 : 0 : zxdh_eth_dev_init(struct rte_eth_dev *eth_dev)
2203 : : {
2204 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
2205 : 0 : struct zxdh_hw *hw = eth_dev->data->dev_private;
2206 : : int ret = 0;
2207 : :
2208 : 0 : eth_dev->dev_ops = &zxdh_eth_dev_ops;
2209 : :
2210 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
2211 : 0 : eth_dev->dev_ops = &zxdh_eth_dev_secondary_ops;
2212 : 0 : ZXDH_VTPCI_OPS(hw) = &zxdh_dev_pci_ops;
2213 : 0 : return 0;
2214 : : }
2215 : :
2216 : : /* Allocate memory for storing MAC addresses */
2217 : 0 : eth_dev->data->mac_addrs = rte_zmalloc("zxdh_mac",
2218 : : ZXDH_MAX_MAC_ADDRS * RTE_ETHER_ADDR_LEN, 0);
2219 [ # # ]: 0 : if (eth_dev->data->mac_addrs == NULL) {
2220 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate %d bytes store MAC addresses",
2221 : : ZXDH_MAX_MAC_ADDRS * RTE_ETHER_ADDR_LEN);
2222 : 0 : return -ENOMEM;
2223 : : }
2224 : :
2225 : : memset(hw, 0, sizeof(*hw));
2226 : 0 : hw->bar_addr[0] = (uint64_t)pci_dev->mem_resource[0].addr;
2227 [ # # ]: 0 : if (hw->bar_addr[0] == 0) {
2228 : 0 : PMD_DRV_LOG(ERR, "Bad mem resource");
2229 : 0 : return -EIO;
2230 : : }
2231 : :
2232 : 0 : hw->device_id = pci_dev->id.device_id;
2233 : 0 : hw->port_id = eth_dev->data->port_id;
2234 : 0 : hw->eth_dev = eth_dev;
2235 : 0 : hw->speed = RTE_ETH_SPEED_NUM_UNKNOWN;
2236 : 0 : hw->duplex = RTE_ETH_LINK_FULL_DUPLEX;
2237 : 0 : hw->slot_id = ZXDH_INVALID_SLOT_IDX;
2238 : : hw->is_pf = 0;
2239 : :
2240 [ # # ]: 0 : if (is_pf(pci_dev->id.device_id)) {
2241 [ # # # ]: 0 : hw->is_pf = 1;
2242 [ # # ]: 0 : if (is_inic_pf(pci_dev->id.device_id))
2243 : 0 : hw->switchoffload = 1;
2244 : : }
2245 : :
2246 : 0 : ret = zxdh_init_once(eth_dev);
2247 [ # # ]: 0 : if (ret != 0)
2248 : 0 : goto err_zxdh_init;
2249 : :
2250 : 0 : ret = zxdh_init_device(eth_dev);
2251 [ # # ]: 0 : if (ret < 0)
2252 : 0 : goto err_zxdh_init;
2253 : :
2254 : 0 : ret = zxdh_msg_chan_init();
2255 [ # # ]: 0 : if (ret != 0) {
2256 : 0 : PMD_DRV_LOG(ERR, "Failed to init bar msg chan");
2257 : 0 : goto err_zxdh_init;
2258 : : }
2259 : 0 : hw->msg_chan_init = 1;
2260 : :
2261 : 0 : ret = zxdh_msg_chan_hwlock_init(eth_dev);
2262 [ # # ]: 0 : if (ret != 0) {
2263 : 0 : PMD_DRV_LOG(ERR, "zxdh_msg_chan_hwlock_init failed ret %d", ret);
2264 : 0 : goto err_zxdh_init;
2265 : : }
2266 : :
2267 : 0 : ret = zxdh_msg_chan_enable(eth_dev);
2268 [ # # ]: 0 : if (ret != 0) {
2269 : 0 : PMD_DRV_LOG(ERR, "zxdh_msg_bar_chan_enable failed ret %d", ret);
2270 : 0 : goto err_zxdh_init;
2271 : : }
2272 : :
2273 : 0 : ret = zxdh_agent_comm(eth_dev, hw);
2274 [ # # ]: 0 : if (ret != 0)
2275 : 0 : goto err_zxdh_init;
2276 : :
2277 : 0 : ret = zxdh_np_init(eth_dev);
2278 [ # # ]: 0 : if (ret)
2279 : 0 : goto err_zxdh_init;
2280 : :
2281 : 0 : zxdh_flow_init(eth_dev);
2282 : 0 : zxdh_queue_res_get(eth_dev);
2283 : 0 : zxdh_msg_cb_reg(hw);
2284 [ # # ]: 0 : if (zxdh_priv_res_init(hw) != 0)
2285 : 0 : goto err_zxdh_init;
2286 : 0 : ret = zxdh_configure_intr(eth_dev);
2287 [ # # ]: 0 : if (ret != 0)
2288 : 0 : goto err_zxdh_init;
2289 : :
2290 : 0 : ret = zxdh_tables_init(eth_dev);
2291 [ # # ]: 0 : if (ret != 0)
2292 : 0 : goto err_zxdh_init;
2293 : :
2294 : : return ret;
2295 : :
2296 : 0 : err_zxdh_init:
2297 : 0 : zxdh_intr_release(eth_dev);
2298 : 0 : zxdh_np_uninit(eth_dev);
2299 : 0 : zxdh_bar_msg_chan_exit();
2300 : 0 : zxdh_priv_res_free(hw);
2301 : 0 : zxdh_free_sh_res();
2302 : 0 : rte_free(hw->dev_sd);
2303 : 0 : hw->dev_sd = NULL;
2304 : 0 : rte_free(eth_dev->data->mac_addrs);
2305 : 0 : eth_dev->data->mac_addrs = NULL;
2306 : 0 : return ret;
2307 : : }
2308 : :
2309 : : static int
2310 : 0 : zxdh_eth_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
2311 : : struct rte_pci_device *pci_dev)
2312 : : {
2313 : 0 : return rte_eth_dev_pci_generic_probe(pci_dev,
2314 : : sizeof(struct zxdh_hw),
2315 : : zxdh_eth_dev_init);
2316 : : }
2317 : :
2318 : : static int
2319 : 0 : zxdh_eth_dev_uninit(struct rte_eth_dev *eth_dev)
2320 : : {
2321 : : int ret = 0;
2322 : :
2323 : 0 : ret = zxdh_dev_close(eth_dev);
2324 : :
2325 : 0 : return ret;
2326 : : }
2327 : :
2328 : : static int
2329 : 0 : zxdh_eth_pci_remove(struct rte_pci_device *pci_dev)
2330 : : {
2331 : 0 : int ret = rte_eth_dev_pci_generic_remove(pci_dev, zxdh_eth_dev_uninit);
2332 : :
2333 : 0 : return ret;
2334 : : }
2335 : :
2336 : : static const struct rte_pci_id pci_id_zxdh_map[] = {
2337 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E310_PF_DEVICEID)},
2338 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E310_VF_DEVICEID)},
2339 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E312_PF_DEVICEID)},
2340 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E312_VF_DEVICEID)},
2341 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E312S_PF_DEVICEID)},
2342 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E312S_VF_DEVICEID)},
2343 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E316_PF_DEVICEID)},
2344 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E316_VF_DEVICEID)},
2345 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E310_RDMA_PF_DEVICEID)},
2346 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E310_RDMA_VF_DEVICEID)},
2347 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E312_RDMA_PF_DEVICEID)},
2348 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E312_RDMA_VF_DEVICEID)},
2349 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_I510_OVS_PF_DEVICEID)},
2350 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_I510_BOND_PF_DEVICEID)},
2351 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_I511_OVS_PF_DEVICEID)},
2352 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_I511_BOND_PF_DEVICEID)},
2353 : : {.vendor_id = 0, /* sentinel */ },
2354 : : };
2355 : : static struct rte_pci_driver zxdh_pmd = {
2356 : : .id_table = pci_id_zxdh_map,
2357 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
2358 : : .probe = zxdh_eth_pci_probe,
2359 : : .remove = zxdh_eth_pci_remove,
2360 : : };
2361 : :
2362 : 276 : RTE_PMD_REGISTER_PCI(net_zxdh, zxdh_pmd);
2363 : : RTE_PMD_REGISTER_PCI_TABLE(net_zxdh, pci_id_zxdh_map);
2364 : : RTE_PMD_REGISTER_KMOD_DEP(net_zxdh, "* vfio-pci");
2365 [ - + ]: 276 : RTE_LOG_REGISTER_SUFFIX(zxdh_logtype_driver, driver, NOTICE);
2366 [ - + ]: 276 : RTE_LOG_REGISTER_SUFFIX(zxdh_logtype_rx, rx, NOTICE);
2367 [ - + ]: 276 : RTE_LOG_REGISTER_SUFFIX(zxdh_logtype_tx, tx, NOTICE);
2368 [ - + ]: 276 : RTE_LOG_REGISTER_SUFFIX(zxdh_logtype_msg, msg, NOTICE);
|