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