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_shared_data g_dev_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_net_hdr_dl g_net_hdr_dl[RTE_MAX_ETHPORTS];
27 : : struct zxdh_mtr_res g_mtr_res;
28 : :
29 : : #define ZXDH_INVALID_DTBQUE 0xFFFF
30 : : #define ZXDH_INVALID_SLOT_IDX 0xFFFF
31 : : #define ZXDH_PF_QUEUE_PAIRS_ADDR 0x5742
32 : : #define ZXDH_VF_QUEUE_PAIRS_ADDR 0x5744
33 : : #define ZXDH_QUEUE_POOL_ADDR 0x56A0
34 : :
35 : : uint16_t
36 : 0 : zxdh_vport_to_vfid(union zxdh_virport_num v)
37 : : {
38 : : /* epid > 4 is local soft queue. return 1192 */
39 [ # # ]: 0 : if (v.epid > 4)
40 : : return 1192;
41 [ # # ]: 0 : if (v.vf_flag)
42 : 0 : return v.epid * 256 + v.vfid;
43 : : else
44 : 0 : return (v.epid * 8 + v.pfid) + 1152;
45 : : }
46 : :
47 : : static int32_t
48 : 0 : zxdh_dev_infos_get(struct rte_eth_dev *dev,
49 : : struct rte_eth_dev_info *dev_info)
50 : : {
51 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
52 : :
53 : 0 : dev_info->speed_capa = rte_eth_speed_bitflag(hw->speed, RTE_ETH_LINK_FULL_DUPLEX);
54 : 0 : dev_info->max_rx_queues = hw->max_queue_pairs;
55 : 0 : dev_info->max_tx_queues = hw->max_queue_pairs;
56 : 0 : dev_info->min_rx_bufsize = ZXDH_MIN_RX_BUFSIZE;
57 : 0 : dev_info->max_rx_pktlen = ZXDH_MAX_RX_PKTLEN;
58 : 0 : dev_info->max_mac_addrs = ZXDH_MAX_MAC_ADDRS;
59 : : dev_info->rx_offload_capa = (RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
60 : : RTE_ETH_RX_OFFLOAD_VLAN_FILTER |
61 : : RTE_ETH_RX_OFFLOAD_QINQ_STRIP);
62 : : dev_info->rx_offload_capa |= (RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
63 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
64 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
65 : : RTE_ETH_RX_OFFLOAD_OUTER_IPV4_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 : : dev_info->tx_offload_capa |= (RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
81 : : RTE_ETH_TX_OFFLOAD_QINQ_INSERT |
82 : : RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO);
83 : 0 : dev_info->tx_offload_capa |= (RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
84 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
85 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
86 : : RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM |
87 : : RTE_ETH_TX_OFFLOAD_OUTER_UDP_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 = &g_net_hdr_dl[hw->port_id];
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 : :
524 : 0 : ret = zxdh_timedlock(hw, 1000);
525 [ # # ]: 0 : if (ret) {
526 : 0 : PMD_DRV_LOG(ERR, "Acquiring hw lock got failed, timeout");
527 : 0 : return -1;
528 : : }
529 : :
530 [ # # ]: 0 : for (phy_vq_reg = 0; phy_vq_reg < vq_reg_num; phy_vq_reg++) {
531 : 0 : uint32_t addr = ZXDH_QUERES_SHARE_BASE +
532 : 0 : (phy_vq_reg + phy_vq_reg_oft) * sizeof(uint32_t);
533 : 0 : uint32_t var = zxdh_read_bar_reg(dev, ZXDH_BAR0_INDEX, addr);
534 [ # # ]: 0 : if (phy_vq_reg == 0) {
535 [ # # ]: 0 : for (j = (inval_bit + base); j < 32; j += 2) {
536 : : /* Got the available channel & update COI table */
537 [ # # ]: 0 : if ((var & (1 << j)) == 0) {
538 : 0 : var |= (1 << j);
539 : 0 : zxdh_write_bar_reg(dev, ZXDH_BAR0_INDEX, addr, var);
540 : : done = 1;
541 : : break;
542 : : }
543 : : }
544 : : if (done)
545 : : break;
546 [ # # # # ]: 0 : } else if ((phy_vq_reg == (vq_reg_num - 1)) && (res_bit != 0)) {
547 [ # # ]: 0 : for (j = base; j < res_bit; j += 2) {
548 : : /* Got the available channel & update COI table */
549 [ # # ]: 0 : if ((var & (1 << j)) == 0) {
550 : 0 : var |= (1 << j);
551 : 0 : zxdh_write_bar_reg(dev, ZXDH_BAR0_INDEX, addr, var);
552 : : done = 1;
553 : : break;
554 : : }
555 : : }
556 : : if (done)
557 : : break;
558 : : } else {
559 [ # # ]: 0 : for (j = base; j < 32; j += 2) {
560 : : /* Got the available channel & update COI table */
561 [ # # ]: 0 : if ((var & (1 << j)) == 0) {
562 : 0 : var |= (1 << j);
563 : 0 : zxdh_write_bar_reg(dev, ZXDH_BAR0_INDEX, addr, var);
564 : : done = 1;
565 : : break;
566 : : }
567 : : }
568 : : if (done)
569 : : break;
570 : : }
571 : : }
572 : :
573 : 0 : zxdh_release_lock(hw);
574 : : /* check for no channel condition */
575 [ # # ]: 0 : if (done != 1) {
576 : 0 : PMD_DRV_LOG(ERR, "NO availd queues");
577 : 0 : return -1;
578 : : }
579 : : /* reruen available channel ID */
580 : 0 : return (phy_vq_reg + phy_vq_reg_oft) * 32 + j;
581 : : }
582 : :
583 : : static int32_t
584 : 0 : zxdh_acquire_channel(struct rte_eth_dev *dev, uint16_t lch)
585 : : {
586 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
587 : :
588 [ # # ]: 0 : if (hw->channel_context[lch].valid == 1) {
589 : 0 : PMD_DRV_LOG(DEBUG, "Logic channel:%u already acquired Physics channel:%u",
590 : : lch, hw->channel_context[lch].ph_chno);
591 : 0 : return hw->channel_context[lch].ph_chno;
592 : : }
593 : 0 : int32_t pch = zxdh_get_available_channel(dev, zxdh_get_queue_type(lch));
594 : :
595 [ # # ]: 0 : if (pch < 0) {
596 : 0 : PMD_DRV_LOG(ERR, "Failed to acquire channel");
597 : 0 : return -1;
598 : : }
599 : 0 : hw->channel_context[lch].ph_chno = (uint16_t)pch;
600 : 0 : hw->channel_context[lch].valid = 1;
601 : 0 : PMD_DRV_LOG(DEBUG, "Acquire channel success lch:%u --> pch:%d", lch, pch);
602 : 0 : return 0;
603 : : }
604 : :
605 : : static void
606 : 0 : zxdh_init_vring(struct zxdh_virtqueue *vq)
607 : : {
608 : 0 : int32_t size = vq->vq_nentries;
609 : 0 : uint8_t *ring_mem = vq->vq_ring_virt_mem;
610 : :
611 : 0 : memset(ring_mem, 0, vq->vq_ring_size);
612 : :
613 : 0 : vq->vq_used_cons_idx = 0;
614 : 0 : vq->vq_desc_head_idx = 0;
615 : 0 : vq->vq_avail_idx = 0;
616 : 0 : vq->vq_desc_tail_idx = (uint16_t)(vq->vq_nentries - 1);
617 : 0 : vq->vq_free_cnt = vq->vq_nentries;
618 : 0 : memset(vq->vq_descx, 0, sizeof(struct zxdh_vq_desc_extra) * vq->vq_nentries);
619 : 0 : zxdh_vring_init_packed(&vq->vq_packed.ring, ring_mem, ZXDH_PCI_VRING_ALIGN, size);
620 : : zxdh_vring_desc_init_packed(vq, size);
621 : : zxdh_queue_disable_intr(vq);
622 : 0 : }
623 : :
624 : : static int32_t
625 : 0 : zxdh_init_queue(struct rte_eth_dev *dev, uint16_t vtpci_logic_qidx)
626 : : {
627 : 0 : char vq_name[ZXDH_VIRTQUEUE_MAX_NAME_SZ] = {0};
628 : 0 : char vq_hdr_name[ZXDH_VIRTQUEUE_MAX_NAME_SZ] = {0};
629 : : const struct rte_memzone *mz = NULL;
630 : : const struct rte_memzone *hdr_mz = NULL;
631 : : uint32_t size = 0;
632 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
633 : : struct zxdh_virtnet_rx *rxvq = NULL;
634 : : struct zxdh_virtnet_tx *txvq = NULL;
635 : : struct zxdh_virtqueue *vq = NULL;
636 : : size_t sz_hdr_mz = 0;
637 : : void *sw_ring = NULL;
638 : 0 : int32_t queue_type = zxdh_get_queue_type(vtpci_logic_qidx);
639 : 0 : int32_t numa_node = dev->device->numa_node;
640 : : uint16_t vtpci_phy_qidx = 0;
641 : : uint32_t vq_size = 0;
642 : : int32_t ret = 0;
643 : :
644 [ # # ]: 0 : if (hw->channel_context[vtpci_logic_qidx].valid == 0) {
645 : 0 : PMD_DRV_LOG(ERR, "lch %d is invalid", vtpci_logic_qidx);
646 : 0 : return -EINVAL;
647 : : }
648 : 0 : vtpci_phy_qidx = hw->channel_context[vtpci_logic_qidx].ph_chno;
649 : :
650 : 0 : PMD_DRV_LOG(DEBUG, "vtpci_logic_qidx :%d setting up physical queue: %u on NUMA node %d",
651 : : vtpci_logic_qidx, vtpci_phy_qidx, numa_node);
652 : :
653 : : vq_size = ZXDH_QUEUE_DEPTH;
654 : :
655 [ # # ]: 0 : if (ZXDH_VTPCI_OPS(hw)->set_queue_num != NULL)
656 : 0 : ZXDH_VTPCI_OPS(hw)->set_queue_num(hw, vtpci_phy_qidx, vq_size);
657 : :
658 [ # # ]: 0 : snprintf(vq_name, sizeof(vq_name), "port%d_vq%d", dev->data->port_id, vtpci_phy_qidx);
659 : :
660 : : size = RTE_ALIGN_CEIL(sizeof(*vq) + vq_size * sizeof(struct zxdh_vq_desc_extra),
661 : : RTE_CACHE_LINE_SIZE);
662 [ # # ]: 0 : if (queue_type == ZXDH_VTNET_TQ) {
663 : : /*
664 : : * For each xmit packet, allocate a zxdh_net_hdr
665 : : * and indirect ring elements
666 : : */
667 : : sz_hdr_mz = vq_size * sizeof(struct zxdh_tx_region);
668 : : }
669 : :
670 : 0 : vq = rte_zmalloc_socket(vq_name, size, RTE_CACHE_LINE_SIZE, numa_node);
671 [ # # ]: 0 : if (vq == NULL) {
672 : 0 : PMD_DRV_LOG(ERR, "can not allocate vq");
673 : 0 : return -ENOMEM;
674 : : }
675 : 0 : hw->vqs[vtpci_logic_qidx] = vq;
676 : :
677 : 0 : vq->hw = hw;
678 : 0 : vq->vq_queue_index = vtpci_phy_qidx;
679 : 0 : vq->vq_nentries = vq_size;
680 : :
681 : 0 : vq->vq_packed.used_wrap_counter = 1;
682 : 0 : vq->vq_packed.cached_flags = ZXDH_VRING_PACKED_DESC_F_AVAIL;
683 : 0 : vq->vq_packed.event_flags_shadow = 0;
684 [ # # ]: 0 : if (queue_type == ZXDH_VTNET_RQ)
685 : 0 : vq->vq_packed.cached_flags |= ZXDH_VRING_DESC_F_WRITE;
686 : :
687 : : /*
688 : : * Reserve a memzone for vring elements
689 : : */
690 : 0 : size = zxdh_vring_size(hw, vq_size, ZXDH_PCI_VRING_ALIGN);
691 : 0 : vq->vq_ring_size = RTE_ALIGN_CEIL(size, ZXDH_PCI_VRING_ALIGN);
692 : 0 : PMD_DRV_LOG(DEBUG, "vring_size: %d, rounded_vring_size: %d", size, vq->vq_ring_size);
693 : :
694 : 0 : mz = rte_memzone_reserve_aligned(vq_name, vq->vq_ring_size,
695 : : numa_node, RTE_MEMZONE_IOVA_CONTIG,
696 : : ZXDH_PCI_VRING_ALIGN);
697 [ # # ]: 0 : if (mz == NULL) {
698 [ # # ]: 0 : if (rte_errno == EEXIST)
699 : 0 : mz = rte_memzone_lookup(vq_name);
700 [ # # ]: 0 : if (mz == NULL) {
701 : : ret = -ENOMEM;
702 : 0 : goto fail_q_alloc;
703 : : }
704 : : }
705 : :
706 : 0 : memset(mz->addr, 0, mz->len);
707 : :
708 : 0 : vq->vq_ring_mem = mz->iova;
709 : 0 : vq->vq_ring_virt_mem = mz->addr;
710 : :
711 : 0 : zxdh_init_vring(vq);
712 : :
713 [ # # ]: 0 : if (sz_hdr_mz) {
714 : 0 : snprintf(vq_hdr_name, sizeof(vq_hdr_name), "port%d_vq%d_hdr",
715 : 0 : dev->data->port_id, vtpci_phy_qidx);
716 : 0 : hdr_mz = rte_memzone_reserve_aligned(vq_hdr_name, sz_hdr_mz,
717 : : numa_node, RTE_MEMZONE_IOVA_CONTIG,
718 : : RTE_CACHE_LINE_SIZE);
719 [ # # ]: 0 : if (hdr_mz == NULL) {
720 [ # # ]: 0 : if (rte_errno == EEXIST)
721 : 0 : hdr_mz = rte_memzone_lookup(vq_hdr_name);
722 [ # # ]: 0 : if (hdr_mz == NULL) {
723 : : ret = -ENOMEM;
724 : 0 : goto fail_q_alloc;
725 : : }
726 : : }
727 : : }
728 : :
729 [ # # ]: 0 : if (queue_type == ZXDH_VTNET_RQ) {
730 : : size_t sz_sw = (ZXDH_MBUF_BURST_SZ + vq_size) * sizeof(vq->sw_ring[0]);
731 : :
732 : 0 : sw_ring = rte_zmalloc_socket("sw_ring", sz_sw, RTE_CACHE_LINE_SIZE, numa_node);
733 [ # # ]: 0 : if (!sw_ring) {
734 : 0 : PMD_DRV_LOG(ERR, "can not allocate RX soft ring");
735 : : ret = -ENOMEM;
736 : 0 : goto fail_q_alloc;
737 : : }
738 : :
739 : 0 : vq->sw_ring = sw_ring;
740 : : rxvq = &vq->rxq;
741 : 0 : rxvq->vq = vq;
742 : 0 : rxvq->port_id = dev->data->port_id;
743 : 0 : rxvq->mz = mz;
744 : : } else { /* queue_type == VTNET_TQ */
745 : 0 : txvq = &vq->txq;
746 : 0 : txvq->vq = vq;
747 : 0 : txvq->port_id = dev->data->port_id;
748 : 0 : txvq->mz = mz;
749 : 0 : txvq->zxdh_net_hdr_mz = hdr_mz;
750 : 0 : txvq->zxdh_net_hdr_mem = hdr_mz->iova;
751 : : }
752 : :
753 : 0 : vq->offset = offsetof(struct rte_mbuf, buf_iova);
754 [ # # ]: 0 : if (queue_type == ZXDH_VTNET_TQ) {
755 : 0 : struct zxdh_tx_region *txr = hdr_mz->addr;
756 : : uint32_t i;
757 : :
758 : : memset(txr, 0, vq_size * sizeof(*txr));
759 [ # # ]: 0 : for (i = 0; i < vq_size; i++) {
760 : : /* first indirect descriptor is always the tx header */
761 : 0 : struct zxdh_vring_packed_desc *start_dp = txr[i].tx_packed_indir;
762 : :
763 : : zxdh_vring_desc_init_indirect_packed(start_dp,
764 : : RTE_DIM(txr[i].tx_packed_indir));
765 : 0 : start_dp->addr = txvq->zxdh_net_hdr_mem + i * sizeof(*txr) +
766 : : offsetof(struct zxdh_tx_region, tx_hdr);
767 : : /* length will be updated to actual pi hdr size when xmit pkt */
768 : 0 : start_dp->len = 0;
769 : : }
770 : : }
771 [ # # ]: 0 : if (ZXDH_VTPCI_OPS(hw)->setup_queue(hw, vq) < 0) {
772 : 0 : PMD_DRV_LOG(ERR, "setup_queue failed");
773 : 0 : return -EINVAL;
774 : : }
775 : : return 0;
776 : 0 : fail_q_alloc:
777 : 0 : rte_free(sw_ring);
778 : 0 : rte_memzone_free(hdr_mz);
779 : 0 : rte_memzone_free(mz);
780 : 0 : rte_free(vq);
781 : 0 : return ret;
782 : : }
783 : :
784 : : static int
785 : 0 : zxdh_inic_pf_init_qid(struct zxdh_hw *hw)
786 : : {
787 : : uint16_t start_qid, enabled_qp;
788 : 0 : int ret = zxdh_inic_pf_get_qp_from_vcb(hw, hw->vfid, &start_qid, &enabled_qp);
789 : :
790 [ # # ]: 0 : if (ret != 0) {
791 : 0 : PMD_DRV_LOG(ERR, "vqm_vfid %u, get_qp_from_vcb fail", hw->vfid);
792 : 0 : return ret;
793 : : }
794 : :
795 : 0 : uint16_t i, num_queues = rte_read16(&hw->common_cfg->num_queues);
796 [ # # ]: 0 : PMD_DRV_LOG(INFO, "vqm_vfid:%u, get num_queues:%u (%s CQ)",
797 : : hw->vfid, num_queues, (num_queues & 0x1) ? "with" : "without");
798 [ # # ]: 0 : for (i = 0; i < (num_queues & 0xfffe); ++i) {
799 : 0 : hw->channel_context[i].ph_chno = start_qid + i;
800 : 0 : hw->channel_context[i].valid = 1;
801 : : }
802 : : return 0;
803 : : }
804 : :
805 : : static int32_t
806 : 0 : zxdh_alloc_queues(struct rte_eth_dev *dev)
807 : : {
808 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
809 : 0 : u_int16_t rxq_num = hw->rx_qnum;
810 : 0 : u_int16_t txq_num = hw->tx_qnum;
811 [ # # ]: 0 : uint16_t nr_vq = (rxq_num > txq_num) ? 2 * rxq_num : 2 * txq_num;
812 : 0 : hw->vqs = rte_zmalloc(NULL, sizeof(struct zxdh_virtqueue *) * nr_vq, 0);
813 : : uint16_t lch, i;
814 : :
815 [ # # ]: 0 : if (!hw->vqs) {
816 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate %d vqs", nr_vq);
817 : 0 : return -ENOMEM;
818 : : }
819 : :
820 [ # # # # ]: 0 : if (hw->switchoffload && !(hw->host_features & (1ULL << ZXDH_F_RING_PACKED))) {
821 [ # # ]: 0 : if (zxdh_inic_pf_init_qid(hw) != 0)
822 : 0 : goto free;
823 : :
824 [ # # ]: 0 : for (i = 0 ; i < rxq_num; i++) {
825 : 0 : lch = i * 2;
826 [ # # ]: 0 : if (zxdh_init_queue(dev, lch) < 0) {
827 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc virtio queue");
828 : 0 : goto free;
829 : : }
830 : : }
831 [ # # ]: 0 : for (i = 0 ; i < txq_num; i++) {
832 : 0 : lch = i * 2 + 1;
833 [ # # ]: 0 : if (zxdh_init_queue(dev, lch) < 0) {
834 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc virtio queue");
835 : 0 : goto free;
836 : : }
837 : : }
838 : : return 0;
839 : : }
840 : :
841 [ # # ]: 0 : for (i = 0 ; i < rxq_num; i++) {
842 : 0 : lch = i * 2;
843 [ # # ]: 0 : if (zxdh_acquire_channel(dev, lch) < 0) {
844 : 0 : PMD_DRV_LOG(ERR, "Failed to acquire the channels");
845 : 0 : goto free;
846 : : }
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 [ # # ]: 0 : for (i = 0 ; i < txq_num; i++) {
853 : 0 : lch = i * 2 + 1;
854 [ # # ]: 0 : if (zxdh_acquire_channel(dev, lch) < 0) {
855 : 0 : PMD_DRV_LOG(ERR, "Failed to acquire the channels");
856 : 0 : goto free;
857 : : }
858 [ # # ]: 0 : if (zxdh_init_queue(dev, lch) < 0) {
859 : 0 : PMD_DRV_LOG(ERR, "Failed to alloc virtio queue");
860 : 0 : goto free;
861 : : }
862 : : }
863 : : return 0;
864 : :
865 : 0 : free:
866 : 0 : zxdh_free_queues(dev);
867 : 0 : return -1;
868 : : }
869 : :
870 : : static int
871 : 0 : zxdh_vlan_offload_configure(struct rte_eth_dev *dev)
872 : : {
873 : : int ret;
874 : : int mask = RTE_ETH_VLAN_STRIP_MASK | RTE_ETH_VLAN_FILTER_MASK | RTE_ETH_QINQ_STRIP_MASK;
875 : :
876 : 0 : ret = zxdh_dev_vlan_offload_set(dev, mask);
877 [ # # ]: 0 : if (ret) {
878 : 0 : PMD_DRV_LOG(ERR, "vlan offload set error");
879 : 0 : return -1;
880 : : }
881 : :
882 : : return 0;
883 : : }
884 : :
885 : : static int
886 : 0 : zxdh_rx_csum_lro_offload_configure(struct rte_eth_dev *dev)
887 : : {
888 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
889 : : struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
890 : 0 : uint32_t need_accelerator = rxmode->offloads & (RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
891 : : RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
892 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
893 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
894 : : RTE_ETH_RX_OFFLOAD_TCP_LRO);
895 : : int ret;
896 : :
897 [ # # ]: 0 : if (hw->is_pf) {
898 : 0 : struct zxdh_port_attr_table port_attr = {0};
899 : 0 : zxdh_get_port_attr(hw, hw->vport.vport, &port_attr);
900 : 0 : port_attr.outer_ip_checksum_offload =
901 : 0 : (rxmode->offloads & RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM) ? true : false;
902 : 0 : port_attr.ip_checksum_offload =
903 : 0 : (rxmode->offloads & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM) ? true : false;
904 : 0 : port_attr.tcp_udp_checksum_offload =
905 : 0 : (rxmode->offloads & (RTE_ETH_RX_OFFLOAD_UDP_CKSUM | RTE_ETH_RX_OFFLOAD_TCP_CKSUM))
906 : 0 : ? true : false;
907 : 0 : port_attr.lro_offload =
908 : 0 : (rxmode->offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) ? true : false;
909 : 0 : port_attr.accelerator_offload_flag = need_accelerator ? true : false;
910 : 0 : ret = zxdh_set_port_attr(hw, hw->vport.vport, &port_attr);
911 [ # # ]: 0 : if (ret) {
912 : 0 : PMD_DRV_LOG(ERR, "%s set port attr failed", __func__);
913 : 0 : return -1;
914 : : }
915 : : } else {
916 : 0 : struct zxdh_msg_info msg_info = {0};
917 : : struct zxdh_port_attr_set_msg *attr_msg = &msg_info.data.port_attr_msg;
918 : :
919 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
920 : 0 : attr_msg->mode = ZXDH_PORT_IP_CHKSUM_FLAG;
921 : 0 : attr_msg->value =
922 : 0 : (rxmode->offloads & RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM) ? true : false;
923 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
924 [ # # ]: 0 : if (ret) {
925 : 0 : PMD_DRV_LOG(ERR, "%s outer ip cksum config failed", __func__);
926 : 0 : return -1;
927 : : }
928 : :
929 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
930 : 0 : attr_msg->mode = ZXDH_PORT_OUTER_IP_CHECKSUM_OFFLOAD_FLAG;
931 : 0 : attr_msg->value = (rxmode->offloads & RTE_ETH_RX_OFFLOAD_IPV4_CKSUM) ? true : false;
932 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
933 [ # # ]: 0 : if (ret) {
934 : 0 : PMD_DRV_LOG(ERR, "%s ip_checksum config failed to send msg", __func__);
935 : 0 : return -1;
936 : : }
937 : :
938 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
939 : 0 : attr_msg->mode = ZXDH_PORT_TCP_UDP_CHKSUM_FLAG;
940 : 0 : attr_msg->value = (rxmode->offloads &
941 : : (RTE_ETH_RX_OFFLOAD_UDP_CKSUM | RTE_ETH_RX_OFFLOAD_TCP_CKSUM)) ?
942 : 0 : true : false;
943 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
944 [ # # ]: 0 : if (ret) {
945 : 0 : PMD_DRV_LOG(ERR, "%s tcp_udp_checksum config failed to send msg", __func__);
946 : 0 : return -1;
947 : : }
948 : :
949 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
950 : 0 : attr_msg->mode = ZXDH_PORT_LRO_OFFLOAD_FLAG;
951 : 0 : attr_msg->value = (rxmode->offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) ? true : false;
952 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
953 [ # # ]: 0 : if (ret) {
954 : 0 : PMD_DRV_LOG(ERR, "%s lro offload config failed to send msg", __func__);
955 : 0 : return -1;
956 : : }
957 : :
958 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
959 : 0 : attr_msg->mode = ZXDH_PORT_ACCELERATOR_OFFLOAD_FLAG_FLAG;
960 : 0 : attr_msg->value = need_accelerator ? true : false;
961 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
962 [ # # ]: 0 : if (ret) {
963 : 0 : PMD_DRV_LOG(ERR,
964 : : "%s accelerator offload config failed to send msg", __func__);
965 : 0 : return -1;
966 : : }
967 : : }
968 : :
969 : : return 0;
970 : : }
971 : :
972 : : static int
973 : 0 : zxdh_dev_conf_offload(struct rte_eth_dev *dev)
974 : : {
975 : : int ret = 0;
976 : :
977 : 0 : ret = zxdh_vlan_offload_configure(dev);
978 [ # # ]: 0 : if (ret) {
979 : 0 : PMD_DRV_LOG(ERR, "zxdh_vlan_offload_configure failed");
980 : 0 : return ret;
981 : : }
982 : :
983 : 0 : ret = zxdh_rss_configure(dev);
984 [ # # ]: 0 : if (ret) {
985 : 0 : PMD_DRV_LOG(ERR, "rss configure failed");
986 : 0 : return ret;
987 : : }
988 : :
989 : 0 : ret = zxdh_rx_csum_lro_offload_configure(dev);
990 [ # # ]: 0 : if (ret) {
991 : 0 : PMD_DRV_LOG(ERR, "rx csum lro configure failed");
992 : 0 : return ret;
993 : : }
994 : :
995 : : return 0;
996 : : }
997 : :
998 : : static int
999 : 0 : zxdh_rss_qid_config(struct rte_eth_dev *dev)
1000 : : {
1001 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1002 : 0 : struct zxdh_port_attr_table port_attr = {0};
1003 : 0 : struct zxdh_msg_info msg_info = {0};
1004 : : int ret = 0;
1005 : :
1006 [ # # ]: 0 : if (hw->is_pf) {
1007 : 0 : ret = zxdh_get_port_attr(hw, hw->vport.vport, &port_attr);
1008 : 0 : port_attr.port_base_qid = hw->channel_context[0].ph_chno & 0xfff;
1009 : :
1010 : 0 : ret = zxdh_set_port_attr(hw, hw->vport.vport, &port_attr);
1011 [ # # ]: 0 : if (ret) {
1012 : 0 : PMD_DRV_LOG(ERR, "PF:%d port_base_qid insert failed", hw->vfid);
1013 : 0 : return ret;
1014 : : }
1015 : : } else {
1016 : : struct zxdh_port_attr_set_msg *attr_msg = &msg_info.data.port_attr_msg;
1017 : :
1018 : 0 : zxdh_msg_head_build(hw, ZXDH_PORT_ATTRS_SET, &msg_info);
1019 : 0 : attr_msg->mode = ZXDH_PORT_BASE_QID_FLAG;
1020 : 0 : attr_msg->value = hw->channel_context[0].ph_chno & 0xfff;
1021 : 0 : ret = zxdh_vf_send_msg_to_pf(dev, &msg_info, sizeof(msg_info), NULL, 0);
1022 [ # # ]: 0 : if (ret) {
1023 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: port 0x%x msg type %d",
1024 : : hw->vport.vport, ZXDH_PORT_BASE_QID_FLAG);
1025 : 0 : return ret;
1026 : : }
1027 : : }
1028 : : return ret;
1029 : : }
1030 : :
1031 : : static int32_t
1032 : 0 : zxdh_dev_configure(struct rte_eth_dev *dev)
1033 : : {
1034 : 0 : const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
1035 : 0 : const struct rte_eth_txmode *txmode = &dev->data->dev_conf.txmode;
1036 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1037 : 0 : uint64_t rx_offloads = rxmode->offloads;
1038 : : int32_t ret = 0;
1039 : :
1040 [ # # ]: 0 : if (dev->data->nb_rx_queues > hw->max_queue_pairs ||
1041 [ # # ]: 0 : dev->data->nb_tx_queues > hw->max_queue_pairs) {
1042 : 0 : PMD_DRV_LOG(ERR, "nb_rx_queues=%d or nb_tx_queues=%d must < (%d)!",
1043 : : dev->data->nb_rx_queues, dev->data->nb_tx_queues, hw->max_queue_pairs);
1044 : 0 : return -EINVAL;
1045 : : }
1046 : :
1047 [ # # ]: 0 : if (rxmode->mq_mode != RTE_ETH_MQ_RX_RSS && rxmode->mq_mode != RTE_ETH_MQ_RX_NONE) {
1048 : 0 : PMD_DRV_LOG(ERR, "Unsupported Rx multi queue mode %d", rxmode->mq_mode);
1049 : 0 : return -EINVAL;
1050 : : }
1051 : :
1052 [ # # ]: 0 : if (txmode->mq_mode != RTE_ETH_MQ_TX_NONE) {
1053 : 0 : PMD_DRV_LOG(ERR, "Unsupported Tx multi queue mode %d", txmode->mq_mode);
1054 : 0 : return -EINVAL;
1055 : : }
1056 : : if (rxmode->mq_mode != RTE_ETH_MQ_RX_RSS && rxmode->mq_mode != RTE_ETH_MQ_RX_NONE) {
1057 : : PMD_DRV_LOG(ERR, "Unsupported Rx multi queue mode %d", rxmode->mq_mode);
1058 : : return -EINVAL;
1059 : : }
1060 : :
1061 : : if (txmode->mq_mode != RTE_ETH_MQ_TX_NONE) {
1062 : : PMD_DRV_LOG(ERR, "Unsupported Tx multi queue mode %d", txmode->mq_mode);
1063 : : return -EINVAL;
1064 : : }
1065 : :
1066 : 0 : ret = zxdh_features_update(hw, rxmode, txmode);
1067 [ # # ]: 0 : if (ret < 0)
1068 : : return ret;
1069 : :
1070 : : /* check if lsc interrupt feature is enabled */
1071 [ # # ]: 0 : if (dev->data->dev_conf.intr_conf.lsc) {
1072 [ # # ]: 0 : if (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)) {
1073 : 0 : PMD_DRV_LOG(ERR, "link status not supported by host");
1074 : 0 : return -ENOTSUP;
1075 : : }
1076 : : }
1077 : :
1078 [ # # ]: 0 : if (rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
1079 : 0 : hw->vlan_offload_cfg.vlan_strip = 1;
1080 : :
1081 : 0 : hw->has_tx_offload = zxdh_tx_offload_enabled(hw);
1082 : 0 : hw->has_rx_offload = zxdh_rx_offload_enabled(hw);
1083 : :
1084 [ # # ]: 0 : if (dev->data->nb_rx_queues == hw->rx_qnum &&
1085 : : dev->data->nb_tx_queues == hw->tx_qnum) {
1086 : 0 : PMD_DRV_LOG(DEBUG, "The queue not need to change. queue_rx %d queue_tx %d",
1087 : : hw->rx_qnum, hw->tx_qnum);
1088 : : /*no queue changed */
1089 : 0 : goto end;
1090 : : }
1091 : :
1092 : 0 : PMD_DRV_LOG(DEBUG, "queue changed need reset");
1093 : : /* Reset the device although not necessary at startup */
1094 : 0 : zxdh_pci_reset(hw);
1095 : :
1096 : : /* Tell the host we've noticed this device. */
1097 : 0 : zxdh_pci_set_status(hw, ZXDH_CONFIG_STATUS_ACK);
1098 : :
1099 : : /* Tell the host we've known how to drive the device. */
1100 : 0 : zxdh_pci_set_status(hw, ZXDH_CONFIG_STATUS_DRIVER);
1101 : : /* The queue needs to be released when reconfiguring*/
1102 [ # # ]: 0 : if (hw->vqs != NULL) {
1103 : 0 : zxdh_dev_free_mbufs(dev);
1104 : 0 : zxdh_free_queues(dev);
1105 : : }
1106 : :
1107 : 0 : hw->rx_qnum = dev->data->nb_rx_queues;
1108 : 0 : hw->tx_qnum = dev->data->nb_tx_queues;
1109 : 0 : ret = zxdh_alloc_queues(dev);
1110 [ # # ]: 0 : if (ret < 0)
1111 : : return ret;
1112 : :
1113 : 0 : zxdh_datach_set(dev);
1114 : :
1115 [ # # ]: 0 : if (zxdh_configure_intr(dev) < 0) {
1116 : 0 : PMD_DRV_LOG(ERR, "Failed to configure interrupt");
1117 : 0 : zxdh_free_queues(dev);
1118 : 0 : return -1;
1119 : : }
1120 : :
1121 : 0 : ret = zxdh_rss_qid_config(dev);
1122 [ # # ]: 0 : if (ret) {
1123 : 0 : PMD_DRV_LOG(ERR, "Failed to configure base qid!");
1124 : 0 : return -1;
1125 : : }
1126 : :
1127 : 0 : zxdh_pci_reinit_complete(hw);
1128 : :
1129 : 0 : end:
1130 : 0 : zxdh_dev_conf_offload(dev);
1131 : 0 : zxdh_update_net_hdr_dl(hw);
1132 : 0 : return ret;
1133 : : }
1134 : :
1135 : : static void
1136 : 0 : zxdh_np_dtb_data_res_free(struct zxdh_hw *hw)
1137 : : {
1138 : 0 : struct rte_eth_dev *dev = hw->eth_dev;
1139 : 0 : struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;
1140 : : int ret;
1141 : : int i;
1142 : :
1143 [ # # # # ]: 0 : if (dtb_data->init_done && dtb_data->bind_device == dev) {
1144 : 0 : ret = zxdh_np_online_uninit(hw->slot_id, dev->data->name, dtb_data->queueid);
1145 [ # # ]: 0 : if (ret)
1146 : 0 : PMD_DRV_LOG(ERR, "%s dpp_np_online_uninstall failed", dev->data->name);
1147 : :
1148 : 0 : rte_memzone_free(dtb_data->dtb_table_conf_mz);
1149 : 0 : dtb_data->dtb_table_conf_mz = NULL;
1150 : 0 : rte_memzone_free(dtb_data->dtb_table_dump_mz);
1151 : 0 : dtb_data->dtb_table_dump_mz = NULL;
1152 : :
1153 [ # # ]: 0 : for (i = 0; i < ZXDH_MAX_BASE_DTB_TABLE_COUNT; i++) {
1154 [ # # ]: 0 : if (dtb_data->dtb_table_bulk_dump_mz[i]) {
1155 : 0 : rte_memzone_free(dtb_data->dtb_table_bulk_dump_mz[i]);
1156 : 0 : dtb_data->dtb_table_bulk_dump_mz[i] = NULL;
1157 : : }
1158 : : }
1159 : 0 : dtb_data->init_done = 0;
1160 : 0 : dtb_data->bind_device = NULL;
1161 : : }
1162 [ # # ]: 0 : if (zxdh_shared_data != NULL)
1163 : 0 : zxdh_shared_data->np_init_done = 0;
1164 : 0 : }
1165 : :
1166 : : static int
1167 : 0 : zxdh_tbl_entry_online_destroy(struct rte_eth_dev *dev)
1168 : : {
1169 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1170 : 0 : struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;
1171 : : uint32_t sdt_no;
1172 : : int ret = 0;
1173 [ # # ]: 0 : if (!dtb_data->init_done)
1174 : : return ret;
1175 [ # # ]: 0 : if (hw->is_pf) {
1176 : 0 : sdt_no = ZXDH_SDT_L2_ENTRY_TABLE0 + hw->hash_search_index;
1177 : 0 : ret = zxdh_np_dtb_hash_online_delete(hw->dev_id, dtb_data->queueid, sdt_no);
1178 [ # # ]: 0 : if (ret)
1179 : 0 : PMD_DRV_LOG(ERR, "%s sdt_no %d failed. code:%d ",
1180 : : dev->data->name, sdt_no, ret);
1181 : 0 : sdt_no = ZXDH_SDT_MC_TABLE0 + hw->hash_search_index;
1182 : 0 : ret = zxdh_np_dtb_hash_online_delete(hw->dev_id, dtb_data->queueid, sdt_no);
1183 [ # # ]: 0 : if (ret)
1184 : 0 : PMD_DRV_LOG(ERR, "%s sdt_no %d failed. code:%d",
1185 : : dev->data->name, sdt_no, ret);
1186 : : }
1187 : : return ret;
1188 : : }
1189 : :
1190 : : static void
1191 : 0 : zxdh_np_uninit(struct rte_eth_dev *dev)
1192 : : {
1193 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1194 : 0 : struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;
1195 : :
1196 [ # # ]: 0 : if (!hw->is_pf)
1197 : : return;
1198 [ # # # # ]: 0 : if (!dtb_data->init_done && !dtb_data->dev_refcnt)
1199 : : return;
1200 : :
1201 : 0 : zxdh_tbl_entry_online_destroy(dev);
1202 : :
1203 [ # # ]: 0 : if (--dtb_data->dev_refcnt == 0)
1204 : 0 : zxdh_np_dtb_data_res_free(hw);
1205 : : }
1206 : :
1207 : : static int
1208 : 0 : zxdh_tables_uninit(struct rte_eth_dev *dev)
1209 : : {
1210 : : int ret;
1211 : :
1212 : 0 : ret = zxdh_port_attr_uninit(dev);
1213 [ # # ]: 0 : if (ret) {
1214 : 0 : PMD_DRV_LOG(ERR, "zxdh_port_attr_uninit failed");
1215 : 0 : return ret;
1216 : : }
1217 : :
1218 : 0 : ret = zxdh_promisc_table_uninit(dev);
1219 [ # # ]: 0 : if (ret) {
1220 : 0 : PMD_DRV_LOG(ERR, "uninit promisc_table failed");
1221 : 0 : return ret;
1222 : : }
1223 : :
1224 : : return ret;
1225 : : }
1226 : :
1227 : : static int
1228 : 0 : zxdh_dev_stop(struct rte_eth_dev *dev)
1229 : : {
1230 : : uint16_t i;
1231 : : int ret = 0;
1232 : :
1233 [ # # ]: 0 : if (dev->data->dev_started == 0)
1234 : : return 0;
1235 : :
1236 : 0 : ret = zxdh_intr_disable(dev);
1237 [ # # ]: 0 : if (ret) {
1238 : 0 : PMD_DRV_LOG(ERR, "intr disable failed");
1239 : 0 : goto end;
1240 : : }
1241 : :
1242 : 0 : ret = zxdh_dev_set_link_down(dev);
1243 [ # # ]: 0 : if (ret) {
1244 : 0 : PMD_DRV_LOG(ERR, "set port %s link down failed!", dev->device->name);
1245 : 0 : goto end;
1246 : : }
1247 : :
1248 : 0 : end:
1249 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++)
1250 : 0 : dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
1251 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++)
1252 : 0 : dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
1253 : :
1254 : : return ret;
1255 : : }
1256 : :
1257 : : static int
1258 : 0 : zxdh_dev_close(struct rte_eth_dev *dev)
1259 : : {
1260 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1261 : : int ret = 0;
1262 : :
1263 : 0 : ret = zxdh_dev_stop(dev);
1264 [ # # ]: 0 : if (ret != 0) {
1265 : 0 : PMD_DRV_LOG(ERR, "stop port %s failed.", dev->device->name);
1266 : 0 : return -1;
1267 : : }
1268 : :
1269 : 0 : ret = zxdh_tables_uninit(dev);
1270 [ # # ]: 0 : if (ret != 0) {
1271 : 0 : PMD_DRV_LOG(ERR, "%s :tables uninit %s failed", __func__, dev->device->name);
1272 : 0 : return -1;
1273 : : }
1274 : :
1275 [ # # ]: 0 : if (zxdh_shared_data != NULL) {
1276 : 0 : zxdh_mtr_release(dev);
1277 : 0 : zxdh_flow_release(dev);
1278 : : }
1279 : :
1280 : 0 : zxdh_intr_release(dev);
1281 : 0 : zxdh_np_uninit(dev);
1282 : 0 : zxdh_pci_reset(hw);
1283 : :
1284 : 0 : zxdh_dev_free_mbufs(dev);
1285 : 0 : zxdh_free_queues(dev);
1286 : :
1287 : 0 : zxdh_bar_msg_chan_exit();
1288 : :
1289 [ # # ]: 0 : if (dev->data->mac_addrs != NULL) {
1290 : 0 : rte_free(dev->data->mac_addrs);
1291 : 0 : dev->data->mac_addrs = NULL;
1292 : : }
1293 : :
1294 : : return ret;
1295 : : }
1296 : :
1297 : : static int32_t
1298 : 0 : zxdh_set_rxtx_funcs(struct rte_eth_dev *eth_dev)
1299 : : {
1300 [ # # ]: 0 : struct zxdh_hw *hw = eth_dev->data->dev_private;
1301 : :
1302 [ # # ]: 0 : if (!zxdh_pci_with_feature(hw, ZXDH_NET_F_MRG_RXBUF)) {
1303 : 0 : PMD_DRV_LOG(ERR, "port %u not support rx mergeable", eth_dev->data->port_id);
1304 : 0 : return -1;
1305 : : }
1306 : 0 : eth_dev->tx_pkt_prepare = zxdh_xmit_pkts_prepare;
1307 : 0 : eth_dev->tx_pkt_burst = &zxdh_xmit_pkts_packed;
1308 : 0 : eth_dev->rx_pkt_burst = &zxdh_recv_pkts_packed;
1309 : :
1310 : 0 : return 0;
1311 : : }
1312 : :
1313 : : static int
1314 : 0 : zxdh_mac_config(struct rte_eth_dev *eth_dev)
1315 : : {
1316 : 0 : struct zxdh_hw *hw = eth_dev->data->dev_private;
1317 : 0 : struct zxdh_msg_info msg_info = {0};
1318 : : int ret = 0;
1319 : :
1320 [ # # ]: 0 : if (hw->is_pf) {
1321 : 0 : ret = zxdh_add_mac_table(hw, hw->vport.vport,
1322 : 0 : ð_dev->data->mac_addrs[0], hw->hash_search_index, 0, 0);
1323 [ # # ]: 0 : if (ret) {
1324 : 0 : PMD_DRV_LOG(ERR, "Failed to add mac: port 0x%x", hw->vport.vport);
1325 : 0 : return ret;
1326 : : }
1327 : 0 : hw->uc_num++;
1328 : : } else {
1329 : : struct zxdh_mac_filter *mac_filter = &msg_info.data.mac_filter_msg;
1330 : 0 : mac_filter->filter_flag = 0xff;
1331 : 0 : mac_filter->mac = eth_dev->data->mac_addrs[0];
1332 : 0 : zxdh_msg_head_build(hw, ZXDH_MAC_ADD, &msg_info);
1333 : 0 : ret = zxdh_vf_send_msg_to_pf(eth_dev, &msg_info, sizeof(msg_info), NULL, 0);
1334 [ # # ]: 0 : if (ret) {
1335 : 0 : PMD_DRV_LOG(ERR, "Failed to send msg: msg type %d", ZXDH_MAC_ADD);
1336 : 0 : return ret;
1337 : : }
1338 : 0 : hw->uc_num++;
1339 : : }
1340 : : return ret;
1341 : : }
1342 : :
1343 : : static int
1344 : 0 : zxdh_dev_start(struct rte_eth_dev *dev)
1345 : : {
1346 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1347 : : struct zxdh_virtqueue *vq;
1348 : : int32_t ret;
1349 : : uint16_t logic_qidx;
1350 : : uint16_t i;
1351 : :
1352 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
1353 : 0 : logic_qidx = 2 * i + ZXDH_RQ_QUEUE_IDX;
1354 : 0 : ret = zxdh_dev_rx_queue_setup_finish(dev, logic_qidx);
1355 [ # # ]: 0 : if (ret < 0)
1356 : 0 : return ret;
1357 : : }
1358 : :
1359 : 0 : zxdh_set_rxtx_funcs(dev);
1360 : 0 : ret = zxdh_intr_enable(dev);
1361 [ # # ]: 0 : if (ret) {
1362 : 0 : PMD_DRV_LOG(ERR, "interrupt enable failed");
1363 : 0 : return -EINVAL;
1364 : : }
1365 : :
1366 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
1367 : 0 : logic_qidx = 2 * i + ZXDH_RQ_QUEUE_IDX;
1368 : 0 : vq = hw->vqs[logic_qidx];
1369 : : /* Flush the old packets */
1370 : 0 : zxdh_queue_rxvq_flush(vq);
1371 : : zxdh_queue_notify(vq);
1372 : : }
1373 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
1374 : 0 : logic_qidx = 2 * i + ZXDH_TQ_QUEUE_IDX;
1375 : 0 : vq = hw->vqs[logic_qidx];
1376 : : zxdh_queue_notify(vq);
1377 : : }
1378 : :
1379 : 0 : hw->admin_status = RTE_ETH_LINK_UP;
1380 : 0 : zxdh_dev_link_update(dev, 0);
1381 : :
1382 : 0 : ret = zxdh_mac_config(hw->eth_dev);
1383 [ # # ]: 0 : if (ret)
1384 : 0 : PMD_DRV_LOG(ERR, "mac config failed");
1385 : :
1386 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++)
1387 : 0 : dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
1388 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++)
1389 : 0 : dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
1390 : :
1391 : : return 0;
1392 : : }
1393 : :
1394 : : static void
1395 : 0 : zxdh_rxq_info_get(struct rte_eth_dev *dev, uint16_t rx_queue_id, struct rte_eth_rxq_info *qinfo)
1396 : : {
1397 : : struct zxdh_virtnet_rx *rxq = NULL;
1398 : :
1399 [ # # ]: 0 : if (rx_queue_id < dev->data->nb_rx_queues)
1400 : 0 : rxq = dev->data->rx_queues[rx_queue_id];
1401 [ # # ]: 0 : if (!rxq) {
1402 : 0 : PMD_RX_LOG(ERR, "rxq is null");
1403 : 0 : return;
1404 : : }
1405 : 0 : qinfo->nb_desc = rxq->vq->vq_nentries;
1406 : 0 : qinfo->conf.rx_free_thresh = rxq->vq->vq_free_thresh;
1407 : 0 : qinfo->conf.offloads = dev->data->dev_conf.rxmode.offloads;
1408 : 0 : qinfo->queue_state = dev->data->rx_queue_state[rx_queue_id];
1409 : : }
1410 : :
1411 : : static void
1412 : 0 : zxdh_txq_info_get(struct rte_eth_dev *dev, uint16_t tx_queue_id, struct rte_eth_txq_info *qinfo)
1413 : : {
1414 : : struct zxdh_virtnet_tx *txq = NULL;
1415 : :
1416 [ # # ]: 0 : if (tx_queue_id < dev->data->nb_tx_queues)
1417 : 0 : txq = dev->data->tx_queues[tx_queue_id];
1418 [ # # ]: 0 : if (!txq) {
1419 : 0 : PMD_TX_LOG(ERR, "txq is null");
1420 : 0 : return;
1421 : : }
1422 : 0 : qinfo->nb_desc = txq->vq->vq_nentries;
1423 : 0 : qinfo->conf.tx_free_thresh = txq->vq->vq_free_thresh;
1424 : 0 : qinfo->conf.offloads = dev->data->dev_conf.txmode.offloads;
1425 : 0 : qinfo->queue_state = dev->data->tx_queue_state[tx_queue_id];
1426 : : }
1427 : :
1428 : : static const uint32_t *
1429 : 0 : zxdh_dev_supported_ptypes_get(struct rte_eth_dev *dev, size_t *ptype_sz)
1430 : : {
1431 : : static const uint32_t ptypes[] = {
1432 : : RTE_PTYPE_L2_ETHER,
1433 : : RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
1434 : : RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
1435 : : RTE_PTYPE_L4_NONFRAG,
1436 : : RTE_PTYPE_L4_FRAG,
1437 : : RTE_PTYPE_L4_TCP,
1438 : : RTE_PTYPE_L4_UDP,
1439 : : RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
1440 : : RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
1441 : : RTE_PTYPE_INNER_L4_NONFRAG,
1442 : : RTE_PTYPE_INNER_L4_FRAG,
1443 : : RTE_PTYPE_INNER_L4_TCP,
1444 : : RTE_PTYPE_INNER_L4_UDP,
1445 : : RTE_PTYPE_UNKNOWN
1446 : : };
1447 : :
1448 [ # # ]: 0 : if (!dev->rx_pkt_burst)
1449 : : return NULL;
1450 : 0 : *ptype_sz = sizeof(ptypes);
1451 : 0 : return ptypes;
1452 : : }
1453 : :
1454 : : /* dev_ops for zxdh, bare necessities for basic operation */
1455 : : static const struct eth_dev_ops zxdh_eth_dev_ops = {
1456 : : .dev_configure = zxdh_dev_configure,
1457 : : .dev_start = zxdh_dev_start,
1458 : : .dev_stop = zxdh_dev_stop,
1459 : : .dev_close = zxdh_dev_close,
1460 : : .dev_infos_get = zxdh_dev_infos_get,
1461 : : .rx_queue_setup = zxdh_dev_rx_queue_setup,
1462 : : .tx_queue_setup = zxdh_dev_tx_queue_setup,
1463 : : .rx_queue_intr_enable = zxdh_dev_rx_queue_intr_enable,
1464 : : .rx_queue_intr_disable = zxdh_dev_rx_queue_intr_disable,
1465 : : .rxq_info_get = zxdh_rxq_info_get,
1466 : : .txq_info_get = zxdh_txq_info_get,
1467 : : .link_update = zxdh_dev_link_update,
1468 : : .dev_set_link_up = zxdh_dev_set_link_up,
1469 : : .dev_set_link_down = zxdh_dev_set_link_down,
1470 : : .mac_addr_add = zxdh_dev_mac_addr_add,
1471 : : .mac_addr_remove = zxdh_dev_mac_addr_remove,
1472 : : .mac_addr_set = zxdh_dev_mac_addr_set,
1473 : : .promiscuous_enable = zxdh_dev_promiscuous_enable,
1474 : : .promiscuous_disable = zxdh_dev_promiscuous_disable,
1475 : : .allmulticast_enable = zxdh_dev_allmulticast_enable,
1476 : : .allmulticast_disable = zxdh_dev_allmulticast_disable,
1477 : : .vlan_tpid_set = zxdh_vlan_tpid_set,
1478 : : .vlan_filter_set = zxdh_dev_vlan_filter_set,
1479 : : .vlan_offload_set = zxdh_dev_vlan_offload_set,
1480 : : .reta_update = zxdh_dev_rss_reta_update,
1481 : : .reta_query = zxdh_dev_rss_reta_query,
1482 : : .rss_hash_update = zxdh_rss_hash_update,
1483 : : .rss_hash_conf_get = zxdh_rss_hash_conf_get,
1484 : : .stats_get = zxdh_dev_stats_get,
1485 : : .stats_reset = zxdh_dev_stats_reset,
1486 : : .xstats_get = zxdh_dev_xstats_get,
1487 : : .xstats_get_names = zxdh_dev_xstats_get_names,
1488 : : .xstats_reset = zxdh_dev_stats_reset,
1489 : : .mtu_set = zxdh_dev_mtu_set,
1490 : : .fw_version_get = zxdh_dev_fw_version_get,
1491 : : .get_module_info = zxdh_dev_get_module_info,
1492 : : .get_module_eeprom = zxdh_dev_get_module_eeprom,
1493 : : .dev_supported_ptypes_get = zxdh_dev_supported_ptypes_get,
1494 : : .mtr_ops_get = zxdh_meter_ops_get,
1495 : : .flow_ops_get = zxdh_flow_ops_get,
1496 : : };
1497 : :
1498 : : static int32_t
1499 : 0 : zxdh_init_device(struct rte_eth_dev *eth_dev)
1500 : : {
1501 : 0 : struct zxdh_hw *hw = eth_dev->data->dev_private;
1502 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
1503 : : int ret = 0;
1504 : :
1505 : 0 : ret = zxdh_read_pci_caps(pci_dev, hw);
1506 [ # # ]: 0 : if (ret) {
1507 : 0 : PMD_DRV_LOG(ERR, "port 0x%x pci caps read failed", hw->port_id);
1508 : 0 : goto err;
1509 : : }
1510 : :
1511 : 0 : zxdh_hw_internal[hw->port_id].zxdh_vtpci_ops = &zxdh_dev_pci_ops;
1512 : 0 : zxdh_pci_reset(hw);
1513 : 0 : zxdh_get_pci_dev_config(hw);
1514 : :
1515 [ # # ]: 0 : rte_ether_addr_copy((struct rte_ether_addr *)hw->mac_addr, ð_dev->data->mac_addrs[0]);
1516 : :
1517 : : /* If host does not support both status and MSI-X then disable LSC */
1518 [ # # # # ]: 0 : if (zxdh_pci_with_feature(hw, ZXDH_NET_F_STATUS) && hw->use_msix != ZXDH_MSIX_NONE)
1519 : 0 : eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
1520 : : else
1521 : 0 : eth_dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
1522 : :
1523 : : return 0;
1524 : :
1525 : : err:
1526 : 0 : PMD_DRV_LOG(ERR, "port %d init device failed", eth_dev->data->port_id);
1527 : 0 : return ret;
1528 : : }
1529 : :
1530 : : static int
1531 : 0 : zxdh_agent_comm(struct rte_eth_dev *eth_dev, struct zxdh_hw *hw)
1532 : : {
1533 [ # # ]: 0 : if (zxdh_phyport_get(eth_dev, &hw->phyport) != 0) {
1534 : 0 : PMD_DRV_LOG(ERR, "Failed to get phyport");
1535 : 0 : return -1;
1536 : : }
1537 : 0 : PMD_DRV_LOG(DEBUG, "Get phyport success: 0x%x", hw->phyport);
1538 : :
1539 : 0 : hw->vfid = zxdh_vport_to_vfid(hw->vport);
1540 : :
1541 [ # # ]: 0 : if (zxdh_hashidx_get(eth_dev, &hw->hash_search_index) != 0) {
1542 : 0 : PMD_DRV_LOG(ERR, "Failed to get hash idx");
1543 : 0 : return -1;
1544 : : }
1545 : :
1546 [ # # ]: 0 : if (zxdh_panelid_get(eth_dev, &hw->panel_id) != 0) {
1547 : 0 : PMD_DRV_LOG(ERR, "Failed to get panel_id");
1548 : 0 : return -1;
1549 : : }
1550 : :
1551 [ # # ]: 0 : if (hw->switchoffload)
1552 : 0 : hw->phyport = 9;
1553 : :
1554 : 0 : PMD_DRV_LOG(DEBUG, "Get panel id success: 0x%x", hw->panel_id);
1555 : :
1556 : 0 : return 0;
1557 : : }
1558 : :
1559 : : static inline int
1560 : 0 : zxdh_dtb_dump_res_init(struct zxdh_hw *hw, ZXDH_DEV_INIT_CTRL_T *dpp_ctrl)
1561 : : {
1562 : : int ret = 0, i;
1563 : :
1564 : 0 : struct zxdh_dtb_bulk_dump_info dtb_dump_baseres[] = {
1565 : : {"sdt_vport_att_table", 4 * 1024 * 1024, ZXDH_SDT_VPORT_ATT_TABLE, NULL},
1566 : : {"sdt_vlan_att_table", 4 * 1024 * 1024, ZXDH_SDT_VLAN_ATT_TABLE, NULL},
1567 : : {"sdt_rss_table", 4 * 1024 * 1024, ZXDH_SDT_RSS_ATT_TABLE, NULL},
1568 : : {"sdt_l2_entry_table0", 5 * 1024 * 1024, ZXDH_SDT_L2_ENTRY_TABLE0, NULL},
1569 : : {"sdt_l2_entry_table1", 5 * 1024 * 1024, ZXDH_SDT_L2_ENTRY_TABLE1, NULL},
1570 : : {"sdt_l2_entry_table2", 5 * 1024 * 1024, ZXDH_SDT_L2_ENTRY_TABLE2, NULL},
1571 : : {"sdt_l2_entry_table3", 5 * 1024 * 1024, ZXDH_SDT_L2_ENTRY_TABLE3, NULL},
1572 : : {"sdt_mc_table0", 5 * 1024 * 1024, ZXDH_SDT_MC_TABLE0, NULL},
1573 : : {"sdt_mc_table1", 5 * 1024 * 1024, ZXDH_SDT_MC_TABLE1, NULL},
1574 : : {"sdt_mc_table2", 5 * 1024 * 1024, ZXDH_SDT_MC_TABLE2, NULL},
1575 : : {"sdt_mc_table3", 5 * 1024 * 1024, ZXDH_SDT_MC_TABLE3, NULL},
1576 : : {"sdt_acl_index_mng", 4 * 1024 * 1024, 30, NULL},
1577 : : {"sdt_fd_table", 4 * 1024 * 1024, ZXDH_SDT_FD_TABLE, NULL},
1578 : : };
1579 : :
1580 : 0 : struct zxdh_dev_shared_data *dev_sd = hw->dev_sd;
1581 : : struct zxdh_dtb_shared_data *dtb_data = &dev_sd->dtb_sd;
1582 : :
1583 [ # # ]: 0 : for (i = 0; i < (int)RTE_DIM(dtb_dump_baseres); i++) {
1584 : 0 : struct zxdh_dtb_bulk_dump_info *p = dtb_dump_baseres + i;
1585 : 0 : char buf[ZXDH_MAX_NAME_LEN] = {0};
1586 : 0 : snprintf(buf, sizeof(buf), "%s_%x", p->mz_name, hw->dev_id);
1587 : 0 : p->mz_name = buf;
1588 : :
1589 : : const struct rte_memzone *generic_dump_mz =
1590 : 0 : rte_memzone_reserve_aligned(p->mz_name, p->mz_size,
1591 : : SOCKET_ID_ANY, 0, RTE_CACHE_LINE_SIZE);
1592 [ # # ]: 0 : if (generic_dump_mz == NULL) {
1593 : 0 : PMD_DRV_LOG(ERR, "Cannot alloc mem for dtb table bulk dump, mz_name is %s, mz_size is %u",
1594 : : p->mz_name, p->mz_size);
1595 : : ret = -ENOMEM;
1596 : 0 : return ret;
1597 : : }
1598 : 0 : p->mz = generic_dump_mz;
1599 : 0 : dpp_ctrl->dump_addr_info[i].vir_addr = generic_dump_mz->addr_64;
1600 : 0 : dpp_ctrl->dump_addr_info[i].phy_addr = generic_dump_mz->iova;
1601 : 0 : dpp_ctrl->dump_addr_info[i].sdt_no = p->sdt_no;
1602 : 0 : dpp_ctrl->dump_addr_info[i].size = p->mz_size;
1603 : :
1604 : 0 : dtb_data->dtb_table_bulk_dump_mz[dpp_ctrl->dump_sdt_num] = generic_dump_mz;
1605 : 0 : dpp_ctrl->dump_sdt_num++;
1606 : : }
1607 : : return ret;
1608 : : }
1609 : :
1610 : : static int
1611 : 0 : zxdh_np_dtb_res_init(struct rte_eth_dev *dev)
1612 : : {
1613 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1614 : 0 : struct zxdh_bar_offset_params param = {0};
1615 : 0 : struct zxdh_bar_offset_res res = {0};
1616 : 0 : char buf[ZXDH_MAX_NAME_LEN] = {0};
1617 : 0 : struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;
1618 : : int ret = 0;
1619 : :
1620 [ # # ]: 0 : if (dtb_data->init_done) {
1621 : 0 : PMD_DRV_LOG(DEBUG, "DTB res already init done, dev %s no need init",
1622 : : dev->device->name);
1623 : 0 : return 0;
1624 : : }
1625 : :
1626 : 0 : dtb_data->queueid = ZXDH_INVALID_DTBQUE;
1627 : 0 : dtb_data->bind_device = dev;
1628 : 0 : dtb_data->dev_refcnt++;
1629 : 0 : dtb_data->init_done = 1;
1630 : :
1631 : 0 : ZXDH_DEV_INIT_CTRL_T *dpp_ctrl = rte_zmalloc(NULL, sizeof(*dpp_ctrl) +
1632 : : sizeof(ZXDH_DTB_ADDR_INFO_T) * 256, 0);
1633 [ # # ]: 0 : if (dpp_ctrl == NULL) {
1634 : 0 : PMD_DRV_LOG(ERR, "dev %s annot allocate memory for dpp_ctrl", dev->device->name);
1635 : : ret = -ENOMEM;
1636 : 0 : goto free_res;
1637 : : }
1638 : 0 : dpp_ctrl->queue_id = 0xff;
1639 : 0 : dpp_ctrl->vport = hw->vport.vport;
1640 : 0 : dpp_ctrl->vector = ZXDH_MSIX_INTR_DTB_VEC;
1641 : 0 : strlcpy(dpp_ctrl->port_name, dev->device->name, sizeof(dpp_ctrl->port_name));
1642 : 0 : dpp_ctrl->pcie_vir_addr = hw->bar_addr[0];
1643 : :
1644 : 0 : param.pcie_id = hw->pcie_id;
1645 : 0 : param.virt_addr = hw->bar_addr[0] + ZXDH_CTRLCH_OFFSET;
1646 : 0 : param.type = ZXDH_URI_NP;
1647 : :
1648 : 0 : ret = zxdh_get_bar_offset(¶m, &res);
1649 [ # # ]: 0 : if (ret) {
1650 : 0 : PMD_DRV_LOG(ERR, "dev %s get npbar offset failed", dev->device->name);
1651 : 0 : goto free_res;
1652 : : }
1653 : 0 : dpp_ctrl->np_bar_len = res.bar_length;
1654 : 0 : dpp_ctrl->np_bar_offset = res.bar_offset;
1655 : :
1656 [ # # ]: 0 : if (!dtb_data->dtb_table_conf_mz) {
1657 : 0 : snprintf(buf, sizeof(buf), "%s_%x", "zxdh_dtb_table_conf_mz", hw->dev_id);
1658 : 0 : const struct rte_memzone *conf_mz = rte_memzone_reserve_aligned(buf,
1659 : : ZXDH_DTB_TABLE_CONF_SIZE, SOCKET_ID_ANY, 0, RTE_CACHE_LINE_SIZE);
1660 : :
1661 [ # # ]: 0 : if (conf_mz == NULL) {
1662 : 0 : PMD_DRV_LOG(ERR,
1663 : : "dev %s annot allocate memory for dtb table conf",
1664 : : dev->device->name);
1665 : : ret = -ENOMEM;
1666 : 0 : goto free_res;
1667 : : }
1668 : 0 : dpp_ctrl->down_vir_addr = conf_mz->addr_64;
1669 : 0 : dpp_ctrl->down_phy_addr = conf_mz->iova;
1670 : 0 : dtb_data->dtb_table_conf_mz = conf_mz;
1671 : : }
1672 : :
1673 [ # # ]: 0 : if (!dtb_data->dtb_table_dump_mz) {
1674 : : memset(buf, '\0', sizeof(buf));
1675 : 0 : snprintf(buf, sizeof(buf), "%s_%x", "zxdh_dtb_table_dump_mz", hw->dev_id);
1676 : 0 : const struct rte_memzone *dump_mz = rte_memzone_reserve_aligned(buf,
1677 : : ZXDH_DTB_TABLE_DUMP_SIZE, SOCKET_ID_ANY, 0, RTE_CACHE_LINE_SIZE);
1678 : :
1679 [ # # ]: 0 : if (dump_mz == NULL) {
1680 : 0 : PMD_DRV_LOG(ERR,
1681 : : "dev %s Cannot allocate memory for dtb table dump",
1682 : : dev->device->name);
1683 : : ret = -ENOMEM;
1684 : 0 : goto free_res;
1685 : : }
1686 : 0 : dpp_ctrl->dump_vir_addr = dump_mz->addr_64;
1687 : 0 : dpp_ctrl->dump_phy_addr = dump_mz->iova;
1688 : 0 : dtb_data->dtb_table_dump_mz = dump_mz;
1689 : : }
1690 : :
1691 : 0 : ret = zxdh_dtb_dump_res_init(hw, dpp_ctrl);
1692 [ # # ]: 0 : if (ret) {
1693 : 0 : PMD_DRV_LOG(ERR, "dev %s zxdh_dtb_dump_res_init failed", dev->device->name);
1694 : 0 : goto free_res;
1695 : : }
1696 : :
1697 : 0 : ret = zxdh_np_host_init(hw->slot_id, dpp_ctrl);
1698 [ # # ]: 0 : if (ret) {
1699 : 0 : PMD_DRV_LOG(ERR, "dev %s dpp host np init failed", dev->device->name);
1700 : 0 : goto free_res;
1701 : : }
1702 : :
1703 : 0 : PMD_DRV_LOG(DEBUG, "dev %s dpp host np init ok.dtb queue %u",
1704 : : dev->device->name, dpp_ctrl->queue_id);
1705 : 0 : dtb_data->queueid = dpp_ctrl->queue_id;
1706 : 0 : rte_free(dpp_ctrl);
1707 : 0 : return 0;
1708 : :
1709 : 0 : free_res:
1710 : 0 : zxdh_np_dtb_data_res_free(hw);
1711 : 0 : rte_free(dpp_ctrl);
1712 : 0 : return ret;
1713 : : }
1714 : :
1715 : : static inline uint16_t
1716 : 0 : zxdh_get_dev_shared_data_idx(uint32_t dev_serial_id)
1717 : : {
1718 : : uint16_t idx = 0;
1719 [ # # ]: 0 : for (; idx < ZXDH_SLOT_MAX; idx++) {
1720 [ # # # # ]: 0 : if (g_dev_sd[idx].serial_id == dev_serial_id || g_dev_sd[idx].serial_id == 0)
1721 : 0 : return idx;
1722 : : }
1723 : :
1724 : 0 : PMD_DRV_LOG(ERR, "dev serial_id[%u] can not found in global dev_share_data arrays",
1725 : : dev_serial_id);
1726 : 0 : return ZXDH_INVALID_SLOT_IDX;
1727 : : }
1728 : :
1729 : 0 : static int zxdh_init_dev_share_data(struct rte_eth_dev *eth_dev)
1730 : : {
1731 : 0 : struct zxdh_hw *hw = eth_dev->data->dev_private;
1732 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
1733 : 0 : uint32_t serial_id = (pci_dev->addr.domain << 16) |
1734 : 0 : (pci_dev->addr.bus << 8) | pci_dev->addr.devid;
1735 : : uint16_t slot_id = 0;
1736 : :
1737 [ # # ]: 0 : if (serial_id <= 0) {
1738 : 0 : PMD_DRV_LOG(ERR, "failed to get pcie bus-info %s", pci_dev->name);
1739 : 0 : return -EINVAL;
1740 : : }
1741 : :
1742 : 0 : slot_id = zxdh_get_dev_shared_data_idx(serial_id);
1743 [ # # ]: 0 : if (slot_id == ZXDH_INVALID_SLOT_IDX)
1744 : : return -EINVAL;
1745 : :
1746 : 0 : hw->slot_id = slot_id;
1747 : 0 : hw->dev_id = (hw->pcie_id << 16) | (hw->slot_id & 0xffff);
1748 : 0 : g_dev_sd[slot_id].serial_id = serial_id;
1749 : 0 : hw->dev_sd = &g_dev_sd[slot_id];
1750 : :
1751 : 0 : return 0;
1752 : : }
1753 : :
1754 : : static int
1755 : 0 : zxdh_init_shared_data(void)
1756 : : {
1757 : : const struct rte_memzone *mz;
1758 : : int ret = 0;
1759 : :
1760 : : rte_spinlock_lock(&zxdh_shared_data_lock);
1761 [ # # ]: 0 : if (zxdh_shared_data == NULL) {
1762 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
1763 : : /* Allocate shared memory. */
1764 : 0 : mz = rte_memzone_reserve("zxdh_pmd_shared_data",
1765 : : sizeof(*zxdh_shared_data), SOCKET_ID_ANY, 0);
1766 [ # # ]: 0 : if (mz == NULL) {
1767 : 0 : PMD_DRV_LOG(ERR, "Cannot allocate zxdh shared data");
1768 : 0 : ret = -rte_errno;
1769 : 0 : goto error;
1770 : : }
1771 : 0 : zxdh_shared_data = mz->addr;
1772 : : memset(zxdh_shared_data, 0, sizeof(*zxdh_shared_data));
1773 : 0 : rte_spinlock_init(&zxdh_shared_data->lock);
1774 : : } else { /* Lookup allocated shared memory. */
1775 : 0 : mz = rte_memzone_lookup("zxdh_pmd_shared_data");
1776 [ # # ]: 0 : if (mz == NULL) {
1777 : 0 : PMD_DRV_LOG(ERR, "Cannot attach zxdh shared data");
1778 : 0 : ret = -rte_errno;
1779 : 0 : goto error;
1780 : : }
1781 : 0 : zxdh_shared_data = mz->addr;
1782 : : }
1783 : : }
1784 : :
1785 : 0 : error:
1786 : : rte_spinlock_unlock(&zxdh_shared_data_lock);
1787 : 0 : return ret;
1788 : : }
1789 : :
1790 : : static void
1791 : 0 : zxdh_free_sh_res(void)
1792 : : {
1793 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
1794 : : rte_spinlock_lock(&zxdh_shared_data_lock);
1795 [ # # # # ]: 0 : if (zxdh_shared_data != NULL && zxdh_shared_data->init_done &&
1796 [ # # ]: 0 : (--zxdh_shared_data->dev_refcnt == 0)) {
1797 : 0 : rte_mempool_free(zxdh_shared_data->flow_mp);
1798 : 0 : rte_mempool_free(zxdh_shared_data->mtr_mp);
1799 : 0 : rte_mempool_free(zxdh_shared_data->mtr_profile_mp);
1800 : 0 : rte_mempool_free(zxdh_shared_data->mtr_policy_mp);
1801 : : }
1802 : : rte_spinlock_unlock(&zxdh_shared_data_lock);
1803 : : }
1804 : 0 : }
1805 : :
1806 : : static int
1807 : 0 : zxdh_init_sh_res(struct zxdh_shared_data *sd)
1808 : : {
1809 : : const char *MZ_ZXDH_FLOW_MP = "zxdh_flow_mempool";
1810 : : const char *MZ_ZXDH_MTR_MP = "zxdh_mtr_mempool";
1811 : : const char *MZ_ZXDH_MTR_PROFILE_MP = "zxdh_mtr_profile_mempool";
1812 : : const char *MZ_ZXDH_MTR_POLICY_MP = "zxdh_mtr_policy_mempool";
1813 : : struct rte_mempool *flow_mp = NULL;
1814 : : struct rte_mempool *mtr_mp = NULL;
1815 : : struct rte_mempool *mtr_profile_mp = NULL;
1816 : : struct rte_mempool *mtr_policy_mp = NULL;
1817 : :
1818 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
1819 : 0 : flow_mp = rte_mempool_create(MZ_ZXDH_FLOW_MP, ZXDH_MAX_FLOW_NUM,
1820 : : sizeof(struct zxdh_flow), 64, 0,
1821 : : NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);
1822 [ # # ]: 0 : if (flow_mp == NULL) {
1823 : 0 : PMD_DRV_LOG(ERR, "Cannot allocate zxdh flow mempool");
1824 : 0 : goto error;
1825 : : }
1826 : 0 : mtr_mp = rte_mempool_create(MZ_ZXDH_MTR_MP, ZXDH_MAX_MTR_NUM,
1827 : : sizeof(struct zxdh_mtr_object), 64, 0,
1828 : : NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);
1829 [ # # ]: 0 : if (mtr_mp == NULL) {
1830 : 0 : PMD_DRV_LOG(ERR, "Cannot allocate zxdh mtr mempool");
1831 : 0 : goto error;
1832 : : }
1833 : 0 : mtr_profile_mp = rte_mempool_create(MZ_ZXDH_MTR_PROFILE_MP,
1834 : : MAX_MTR_PROFILE_NUM, sizeof(struct zxdh_meter_profile),
1835 : : 64, 0, NULL, NULL, NULL,
1836 : : NULL, SOCKET_ID_ANY, 0);
1837 [ # # ]: 0 : if (mtr_profile_mp == NULL) {
1838 : 0 : PMD_DRV_LOG(ERR, "Cannot allocate zxdh mtr profile mempool");
1839 : 0 : goto error;
1840 : : }
1841 : 0 : mtr_policy_mp = rte_mempool_create(MZ_ZXDH_MTR_POLICY_MP,
1842 : : ZXDH_MAX_POLICY_NUM, sizeof(struct zxdh_meter_policy),
1843 : : 64, 0, NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0);
1844 [ # # ]: 0 : if (mtr_policy_mp == NULL) {
1845 : 0 : PMD_DRV_LOG(ERR, "Cannot allocate zxdh mtr profile mempool");
1846 : 0 : goto error;
1847 : : }
1848 : 0 : sd->flow_mp = flow_mp;
1849 : 0 : sd->mtr_mp = mtr_mp;
1850 : 0 : sd->mtr_profile_mp = mtr_profile_mp;
1851 : 0 : sd->mtr_policy_mp = mtr_policy_mp;
1852 : 0 : TAILQ_INIT(&zxdh_shared_data->meter_profile_list);
1853 : 0 : TAILQ_INIT(&zxdh_shared_data->mtr_list);
1854 : 0 : TAILQ_INIT(&zxdh_shared_data->mtr_policy_list);
1855 : : }
1856 : : return 0;
1857 : :
1858 : 0 : error:
1859 : 0 : rte_mempool_free(mtr_policy_mp);
1860 : 0 : rte_mempool_free(mtr_profile_mp);
1861 : 0 : rte_mempool_free(mtr_mp);
1862 : 0 : rte_mempool_free(flow_mp);
1863 : 0 : return -rte_errno;
1864 : : }
1865 : :
1866 : : static int
1867 : 0 : zxdh_init_once(struct rte_eth_dev *eth_dev)
1868 : : {
1869 : 0 : struct zxdh_hw *hw = eth_dev->data->dev_private;
1870 : : int ret = 0;
1871 : :
1872 [ # # ]: 0 : if (hw->is_pf) {
1873 : 0 : ret = zxdh_init_dev_share_data(eth_dev);
1874 [ # # ]: 0 : if (ret < 0) {
1875 : 0 : PMD_DRV_LOG(ERR, "init dev share date failed");
1876 : 0 : return ret;
1877 : : }
1878 : : }
1879 : :
1880 [ # # ]: 0 : if (zxdh_init_shared_data())
1881 : : return -1;
1882 : :
1883 : 0 : struct zxdh_shared_data *sd = zxdh_shared_data;
1884 : 0 : rte_spinlock_lock(&sd->lock);
1885 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
1886 [ # # ]: 0 : if (!sd->init_done) {
1887 : 0 : ++sd->secondary_cnt;
1888 : 0 : sd->init_done = true;
1889 : : }
1890 : 0 : goto out;
1891 : : }
1892 : : /* RTE_PROC_PRIMARY */
1893 [ # # ]: 0 : if (!sd->init_done) {
1894 : : /*shared struct and res init */
1895 : 0 : ret = zxdh_init_sh_res(sd);
1896 [ # # ]: 0 : if (ret != 0)
1897 : 0 : goto out;
1898 : 0 : zxdh_flow_global_init();
1899 : : rte_spinlock_init(&g_mtr_res.hw_plcr_res_lock);
1900 : : memset(&g_mtr_res, 0, sizeof(g_mtr_res));
1901 : 0 : sd->init_done = true;
1902 : : }
1903 : 0 : sd->dev_refcnt++;
1904 : 0 : out:
1905 : : rte_spinlock_unlock(&sd->lock);
1906 : 0 : return ret;
1907 : : }
1908 : :
1909 : : static int
1910 : 0 : zxdh_tbl_entry_offline_destroy(struct zxdh_hw *hw)
1911 : : {
1912 : 0 : struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;
1913 : : int ret = 0;
1914 [ # # ]: 0 : if (!dtb_data->init_done)
1915 : : return ret;
1916 [ # # ]: 0 : if (hw->is_pf) {
1917 : : uint32_t sdt_no;
1918 : 0 : sdt_no = ZXDH_SDT_L2_ENTRY_TABLE0 + hw->hash_search_index;
1919 : 0 : ret = zxdh_np_dtb_hash_offline_delete(hw->dev_id, dtb_data->queueid, sdt_no, 0);
1920 [ # # ]: 0 : if (ret)
1921 : 0 : PMD_DRV_LOG(ERR, "sdt_no %d delete failed. code:%d ", sdt_no, ret);
1922 : 0 : sdt_no = ZXDH_SDT_MC_TABLE0 + hw->hash_search_index;
1923 : 0 : ret = zxdh_np_dtb_hash_offline_delete(hw->dev_id, dtb_data->queueid, sdt_no, 0);
1924 [ # # ]: 0 : if (ret)
1925 : 0 : PMD_DRV_LOG(ERR, "sdt_no %d delete failed. code:%d ", sdt_no, ret);
1926 : :
1927 : 0 : ret = zxdh_np_dtb_acl_offline_delete(hw->dev_id, dtb_data->queueid,
1928 : 0 : ZXDH_SDT_FD_TABLE, hw->vport.vport,
1929 : : ZXDH_FLOW_STATS_INGRESS_BASE, 1);
1930 [ # # ]: 0 : if (ret)
1931 : 0 : PMD_DRV_LOG(ERR, "flow offline delete failed. code:%d", ret);
1932 : : }
1933 : : return ret;
1934 : : }
1935 : :
1936 : : static int
1937 : 0 : zxdh_np_init(struct rte_eth_dev *eth_dev)
1938 : : {
1939 : 0 : struct zxdh_hw *hw = eth_dev->data->dev_private;
1940 : 0 : struct zxdh_dtb_shared_data *dtb_data = &hw->dev_sd->dtb_sd;
1941 : : int ret = 0;
1942 : :
1943 [ # # # # ]: 0 : if (hw->is_pf && dtb_data->init_done) {
1944 : 0 : dtb_data->dev_refcnt++;
1945 : 0 : zxdh_tbl_entry_offline_destroy(hw);
1946 : 0 : PMD_DRV_LOG(INFO, "no need to init dtb dtb chanenl %d devref %d",
1947 : : dtb_data->queueid, dtb_data->dev_refcnt);
1948 : 0 : return 0;
1949 : : }
1950 : :
1951 [ # # ]: 0 : if (hw->is_pf) {
1952 : 0 : ret = zxdh_np_dtb_res_init(eth_dev);
1953 [ # # ]: 0 : if (ret) {
1954 : 0 : PMD_DRV_LOG(ERR, "np dtb init failed, ret:%d", ret);
1955 : 0 : return ret;
1956 : : }
1957 : : }
1958 : :
1959 [ # # ]: 0 : if (hw->is_pf) {
1960 : 0 : ret = zxdh_np_se_res_get_and_init(hw->dev_id, ZXDH_SE_STD_NIC_RES_TYPE);
1961 [ # # ]: 0 : if (ret) {
1962 : 0 : PMD_DRV_LOG(ERR, "dpp apt init failed, code:%d ", ret);
1963 : 0 : return -ret;
1964 : : }
1965 [ # # ]: 0 : if (!hw->switchoffload) {
1966 [ # # ]: 0 : if (hw->hash_search_index >= ZXDH_HASHIDX_MAX) {
1967 : 0 : PMD_DRV_LOG(ERR, "invalid hash idx %d", hw->hash_search_index);
1968 : 0 : return -1;
1969 : : }
1970 : 0 : zxdh_tbl_entry_offline_destroy(hw);
1971 : : }
1972 : : }
1973 : :
1974 [ # # ]: 0 : if (zxdh_shared_data != NULL)
1975 : 0 : zxdh_shared_data->np_init_done = 1;
1976 : :
1977 : 0 : PMD_DRV_LOG(DEBUG, "np init ok");
1978 : 0 : return 0;
1979 : : }
1980 : :
1981 : : static int
1982 : 0 : zxdh_tables_init(struct rte_eth_dev *dev)
1983 : : {
1984 : 0 : struct zxdh_hw *hw = dev->data->dev_private;
1985 : : int ret = 0;
1986 : :
1987 : 0 : ret = zxdh_port_attr_init(dev);
1988 [ # # ]: 0 : if (ret) {
1989 : 0 : PMD_DRV_LOG(ERR, "zxdh_port_attr_init failed");
1990 : 0 : return ret;
1991 : : }
1992 : :
1993 : 0 : ret = zxdh_panel_table_init(dev);
1994 [ # # ]: 0 : if (ret) {
1995 : 0 : PMD_DRV_LOG(ERR, "panel table init failed");
1996 : 0 : return ret;
1997 : : }
1998 : :
1999 : 0 : ret = zxdh_promisc_table_init(dev);
2000 [ # # ]: 0 : if (ret) {
2001 : 0 : PMD_DRV_LOG(ERR, "promisc_table_init failed");
2002 : 0 : return ret;
2003 : : }
2004 : :
2005 : 0 : ret = zxdh_vlan_filter_table_init(hw, hw->vport.vport);
2006 [ # # ]: 0 : if (ret) {
2007 : 0 : PMD_DRV_LOG(ERR, "vlan filter table init failed");
2008 : 0 : return ret;
2009 : : }
2010 : :
2011 : 0 : ret = zxdh_port_vlan_table_init(hw, hw->vport.vport);
2012 [ # # ]: 0 : if (ret) {
2013 : 0 : PMD_DRV_LOG(ERR, "port vlan table init failed");
2014 : 0 : return ret;
2015 : : }
2016 : :
2017 : : return ret;
2018 : : }
2019 : :
2020 : : static void
2021 : 0 : zxdh_queue_res_get(struct rte_eth_dev *eth_dev)
2022 : : {
2023 : 0 : struct zxdh_hw *hw = eth_dev->data->dev_private;
2024 : : uint32_t value = 0;
2025 : : uint16_t offset = 0;
2026 : :
2027 : 0 : offset = hw->vport.epid * 8 + hw->vport.pfid;
2028 [ # # ]: 0 : if (hw->is_pf) {
2029 : 0 : hw->max_queue_pairs = *(volatile uint8_t *)(hw->bar_addr[0] +
2030 : : ZXDH_PF_QUEUE_PAIRS_ADDR);
2031 : 0 : PMD_DRV_LOG(DEBUG, "is_pf max_queue_pairs is %x", hw->max_queue_pairs);
2032 : : } else {
2033 : 0 : hw->max_queue_pairs = *(volatile uint8_t *)(hw->bar_addr[0] +
2034 : 0 : ZXDH_VF_QUEUE_PAIRS_ADDR + offset);
2035 : 0 : PMD_DRV_LOG(DEBUG, "is_vf max_queue_pairs is %x", hw->max_queue_pairs);
2036 : : }
2037 : :
2038 : : /* pf/vf read queue start id and queue_max cfg */
2039 : 0 : value = *(volatile uint32_t *)(hw->bar_addr[0] + ZXDH_QUEUE_POOL_ADDR + offset * 4);
2040 : 0 : hw->queue_pool_count = value & 0x0000ffff;
2041 : 0 : hw->queue_pool_start = value >> 16;
2042 [ # # ]: 0 : if (hw->max_queue_pairs > ZXDH_RX_QUEUES_MAX || hw->max_queue_pairs == 0)
2043 : 0 : hw->max_queue_pairs = ZXDH_RX_QUEUES_MAX;
2044 [ # # ]: 0 : if (hw->queue_pool_count > ZXDH_TOTAL_QUEUES_NUM / 2 || hw->queue_pool_count == 0)
2045 : 0 : hw->queue_pool_count = ZXDH_TOTAL_QUEUES_NUM / 2;
2046 [ # # ]: 0 : if (hw->queue_pool_start > ZXDH_TOTAL_QUEUES_NUM / 2)
2047 : 0 : hw->queue_pool_start = 0;
2048 : 0 : }
2049 : :
2050 : : static int
2051 : 0 : zxdh_priv_res_init(struct zxdh_hw *hw)
2052 : : {
2053 [ # # ]: 0 : if (hw->is_pf) {
2054 : 0 : hw->vfinfo = rte_zmalloc("vfinfo", ZXDH_MAX_VF * sizeof(struct vfinfo), 4);
2055 [ # # ]: 0 : if (hw->vfinfo == NULL) {
2056 : 0 : PMD_DRV_LOG(ERR, "vfinfo malloc failed");
2057 : 0 : return -ENOMEM;
2058 : : }
2059 : : } else {
2060 : 0 : hw->vfinfo = NULL;
2061 : : }
2062 : :
2063 : 0 : hw->channel_context = rte_zmalloc("zxdh_chnlctx",
2064 : : sizeof(struct zxdh_chnl_context) * ZXDH_QUEUES_NUM_MAX, 0);
2065 [ # # ]: 0 : if (hw->channel_context == NULL) {
2066 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate channel_context");
2067 : 0 : return -ENOMEM;
2068 : : }
2069 : : return 0;
2070 : : }
2071 : :
2072 : : static void
2073 : 0 : zxdh_priv_res_free(struct zxdh_hw *priv)
2074 : : {
2075 : 0 : rte_free(priv->vfinfo);
2076 : 0 : priv->vfinfo = NULL;
2077 [ # # ]: 0 : if (priv->channel_context != NULL) {
2078 : 0 : rte_free(priv->channel_context);
2079 : 0 : priv->channel_context = NULL;
2080 : : }
2081 : 0 : }
2082 : :
2083 : : static uint8_t
2084 : 0 : is_pf(uint16_t device_id)
2085 : : {
2086 : 0 : return (device_id == ZXDH_E310_PF_DEVICEID ||
2087 [ # # # # : 0 : device_id == ZXDH_E312_PF_DEVICEID ||
# # ]
2088 : : device_id == ZXDH_E312S_PF_DEVICEID ||
2089 : : device_id == ZXDH_E316_PF_DEVICEID ||
2090 : : device_id == ZXDH_E310_RDMA_PF_DEVICEID ||
2091 : : device_id == ZXDH_E312_RDMA_PF_DEVICEID ||
2092 : : device_id == ZXDH_I510_OVS_PF_DEVICEID ||
2093 : : device_id == ZXDH_I510_BOND_PF_DEVICEID ||
2094 : 0 : device_id == ZXDH_I511_OVS_PF_DEVICEID ||
2095 : : device_id == ZXDH_I511_BOND_PF_DEVICEID);
2096 : : }
2097 : :
2098 : : static uint8_t
2099 : : is_inic_pf(uint16_t device_id)
2100 : : {
2101 : : return (device_id == ZXDH_I510_OVS_PF_DEVICEID ||
2102 : : device_id == ZXDH_I510_BOND_PF_DEVICEID ||
2103 : 0 : device_id == ZXDH_I511_OVS_PF_DEVICEID ||
2104 : : device_id == ZXDH_I511_BOND_PF_DEVICEID);
2105 : : }
2106 : :
2107 : : static int
2108 : 0 : zxdh_eth_dev_init(struct rte_eth_dev *eth_dev)
2109 : : {
2110 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
2111 : 0 : struct zxdh_hw *hw = eth_dev->data->dev_private;
2112 : : int ret = 0;
2113 : :
2114 : 0 : eth_dev->dev_ops = &zxdh_eth_dev_ops;
2115 : :
2116 : : /* Allocate memory for storing MAC addresses */
2117 : 0 : eth_dev->data->mac_addrs = rte_zmalloc("zxdh_mac",
2118 : : ZXDH_MAX_MAC_ADDRS * RTE_ETHER_ADDR_LEN, 0);
2119 [ # # ]: 0 : if (eth_dev->data->mac_addrs == NULL) {
2120 : 0 : PMD_DRV_LOG(ERR, "Failed to allocate %d bytes store MAC addresses",
2121 : : ZXDH_MAX_MAC_ADDRS * RTE_ETHER_ADDR_LEN);
2122 : 0 : return -ENOMEM;
2123 : : }
2124 : :
2125 : : memset(hw, 0, sizeof(*hw));
2126 : 0 : hw->bar_addr[0] = (uint64_t)pci_dev->mem_resource[0].addr;
2127 [ # # ]: 0 : if (hw->bar_addr[0] == 0) {
2128 : 0 : PMD_DRV_LOG(ERR, "Bad mem resource");
2129 : 0 : return -EIO;
2130 : : }
2131 : :
2132 : 0 : hw->device_id = pci_dev->id.device_id;
2133 : 0 : hw->port_id = eth_dev->data->port_id;
2134 : 0 : hw->eth_dev = eth_dev;
2135 : 0 : hw->speed = RTE_ETH_SPEED_NUM_UNKNOWN;
2136 : 0 : hw->duplex = RTE_ETH_LINK_FULL_DUPLEX;
2137 : 0 : hw->slot_id = ZXDH_INVALID_SLOT_IDX;
2138 : : hw->is_pf = 0;
2139 : :
2140 [ # # ]: 0 : if (is_pf(pci_dev->id.device_id)) {
2141 [ # # # ]: 0 : hw->is_pf = 1;
2142 [ # # ]: 0 : if (is_inic_pf(pci_dev->id.device_id))
2143 : 0 : hw->switchoffload = 1;
2144 : : }
2145 : :
2146 : 0 : ret = zxdh_init_once(eth_dev);
2147 [ # # ]: 0 : if (ret != 0)
2148 : 0 : goto err_zxdh_init;
2149 : :
2150 : 0 : ret = zxdh_init_device(eth_dev);
2151 [ # # ]: 0 : if (ret < 0)
2152 : 0 : goto err_zxdh_init;
2153 : :
2154 : 0 : ret = zxdh_msg_chan_init();
2155 [ # # ]: 0 : if (ret != 0) {
2156 : 0 : PMD_DRV_LOG(ERR, "Failed to init bar msg chan");
2157 : 0 : goto err_zxdh_init;
2158 : : }
2159 : 0 : hw->msg_chan_init = 1;
2160 : :
2161 : 0 : ret = zxdh_msg_chan_hwlock_init(eth_dev);
2162 [ # # ]: 0 : if (ret != 0) {
2163 : 0 : PMD_DRV_LOG(ERR, "zxdh_msg_chan_hwlock_init failed ret %d", ret);
2164 : 0 : goto err_zxdh_init;
2165 : : }
2166 : :
2167 : 0 : ret = zxdh_msg_chan_enable(eth_dev);
2168 [ # # ]: 0 : if (ret != 0) {
2169 : 0 : PMD_DRV_LOG(ERR, "zxdh_msg_bar_chan_enable failed ret %d", ret);
2170 : 0 : goto err_zxdh_init;
2171 : : }
2172 : :
2173 : 0 : ret = zxdh_agent_comm(eth_dev, hw);
2174 [ # # ]: 0 : if (ret != 0)
2175 : 0 : goto err_zxdh_init;
2176 : :
2177 : 0 : ret = zxdh_np_init(eth_dev);
2178 [ # # ]: 0 : if (ret)
2179 : 0 : goto err_zxdh_init;
2180 : :
2181 : 0 : zxdh_flow_init(eth_dev);
2182 : 0 : zxdh_queue_res_get(eth_dev);
2183 : 0 : zxdh_msg_cb_reg(hw);
2184 [ # # ]: 0 : if (zxdh_priv_res_init(hw) != 0)
2185 : 0 : goto err_zxdh_init;
2186 : 0 : ret = zxdh_configure_intr(eth_dev);
2187 [ # # ]: 0 : if (ret != 0)
2188 : 0 : goto err_zxdh_init;
2189 : :
2190 : 0 : ret = zxdh_tables_init(eth_dev);
2191 [ # # ]: 0 : if (ret != 0)
2192 : 0 : goto err_zxdh_init;
2193 : :
2194 : : return ret;
2195 : :
2196 : 0 : err_zxdh_init:
2197 : 0 : zxdh_intr_release(eth_dev);
2198 : 0 : zxdh_np_uninit(eth_dev);
2199 : 0 : zxdh_bar_msg_chan_exit();
2200 : 0 : zxdh_priv_res_free(hw);
2201 : 0 : zxdh_free_sh_res();
2202 : 0 : rte_free(hw->dev_sd);
2203 : 0 : hw->dev_sd = NULL;
2204 : 0 : rte_free(eth_dev->data->mac_addrs);
2205 : 0 : eth_dev->data->mac_addrs = NULL;
2206 : 0 : return ret;
2207 : : }
2208 : :
2209 : : static int
2210 : 0 : zxdh_eth_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
2211 : : struct rte_pci_device *pci_dev)
2212 : : {
2213 : 0 : return rte_eth_dev_pci_generic_probe(pci_dev,
2214 : : sizeof(struct zxdh_hw),
2215 : : zxdh_eth_dev_init);
2216 : : }
2217 : :
2218 : : static int
2219 : 0 : zxdh_eth_dev_uninit(struct rte_eth_dev *eth_dev)
2220 : : {
2221 : : int ret = 0;
2222 : :
2223 : 0 : ret = zxdh_dev_close(eth_dev);
2224 : :
2225 : 0 : return ret;
2226 : : }
2227 : :
2228 : : static int
2229 : 0 : zxdh_eth_pci_remove(struct rte_pci_device *pci_dev)
2230 : : {
2231 : 0 : int ret = rte_eth_dev_pci_generic_remove(pci_dev, zxdh_eth_dev_uninit);
2232 : :
2233 : 0 : return ret;
2234 : : }
2235 : :
2236 : : static const struct rte_pci_id pci_id_zxdh_map[] = {
2237 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E310_PF_DEVICEID)},
2238 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E310_VF_DEVICEID)},
2239 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E312_PF_DEVICEID)},
2240 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E312_VF_DEVICEID)},
2241 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E312S_PF_DEVICEID)},
2242 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E312S_VF_DEVICEID)},
2243 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E316_PF_DEVICEID)},
2244 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E316_VF_DEVICEID)},
2245 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E310_RDMA_PF_DEVICEID)},
2246 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E310_RDMA_VF_DEVICEID)},
2247 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E312_RDMA_PF_DEVICEID)},
2248 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_E312_RDMA_VF_DEVICEID)},
2249 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_I510_OVS_PF_DEVICEID)},
2250 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_I510_BOND_PF_DEVICEID)},
2251 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_I511_OVS_PF_DEVICEID)},
2252 : : {RTE_PCI_DEVICE(ZXDH_PCI_VENDOR_ID, ZXDH_I511_BOND_PF_DEVICEID)},
2253 : : {.vendor_id = 0, /* sentinel */ },
2254 : : };
2255 : : static struct rte_pci_driver zxdh_pmd = {
2256 : : .id_table = pci_id_zxdh_map,
2257 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
2258 : : .probe = zxdh_eth_pci_probe,
2259 : : .remove = zxdh_eth_pci_remove,
2260 : : };
2261 : :
2262 : 253 : RTE_PMD_REGISTER_PCI(net_zxdh, zxdh_pmd);
2263 : : RTE_PMD_REGISTER_PCI_TABLE(net_zxdh, pci_id_zxdh_map);
2264 : : RTE_PMD_REGISTER_KMOD_DEP(net_zxdh, "* vfio-pci");
2265 [ - + ]: 253 : RTE_LOG_REGISTER_SUFFIX(zxdh_logtype_driver, driver, NOTICE);
2266 [ - + ]: 253 : RTE_LOG_REGISTER_SUFFIX(zxdh_logtype_rx, rx, NOTICE);
2267 [ - + ]: 253 : RTE_LOG_REGISTER_SUFFIX(zxdh_logtype_tx, tx, NOTICE);
2268 [ - + ]: 253 : RTE_LOG_REGISTER_SUFFIX(zxdh_logtype_msg, msg, NOTICE);
|