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