Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
3 : : */
4 : :
5 : : #include "sxe2_ethdev_repr.h"
6 : : #include "sxe2_ethdev.h"
7 : : #include "sxe2_common.h"
8 : : #include "sxe2_common_log.h"
9 : : #include "sxe2_tx.h"
10 : : #include "sxe2_rx.h"
11 : : #include "sxe2_txrx.h"
12 : : #include "sxe2_switchdev.h"
13 : : #include "sxe2_mp.h"
14 : : #include "sxe2_dump.h"
15 : : #include "sxe2_stats.h"
16 : : #include "sxe2_flow.h"
17 : :
18 : : static struct sxe2_pci_map_addr_info sxe2_net_map_addr_info_repr[SXE2_PCI_MAP_RES_MAX_COUNT] = {
19 : : {0, 0, 0},
20 : : { SXE2_TXQ_LEGACY_DBLL(0), 0, 4},
21 : : { SXE2_RXQ_TAIL(0), 0, 4},
22 : : { SXE2_VF_DYN_CTL(0), 0, 4},
23 : : { SXE2_VF_INT_ITR(0, 0), 0, 4},
24 : : { SXE2_BAR4_MSIX_CTL(0), 4, 0x10},
25 : : };
26 : :
27 : : static void sxe2_repr_dev_uinit(struct rte_eth_dev *dev);
28 : :
29 : 0 : static int32_t sxe2_repr_promisc_enable(struct rte_eth_dev *dev __rte_unused)
30 : : {
31 : 0 : return 0;
32 : : }
33 : 0 : static int32_t sxe2_repr_promisc_disable(struct rte_eth_dev *dev __rte_unused)
34 : : {
35 : 0 : return 0;
36 : : }
37 : 0 : static int32_t sxe2_repr_allmulti_enable(struct rte_eth_dev *dev __rte_unused)
38 : : {
39 : 0 : return 0;
40 : : }
41 : 0 : static int32_t sxe2_repr_allmulti_disable(struct rte_eth_dev *dev __rte_unused)
42 : : {
43 : 0 : return 0;
44 : : }
45 : :
46 : 0 : static int32_t sxe2_repr_dev_configure(struct rte_eth_dev *dev)
47 : : {
48 : 0 : dev->data->mtu = SXE2_FRAME_SIZE_MAX - SXE2_ETH_OVERHEAD;
49 : 0 : return 0;
50 : : }
51 : :
52 : 0 : static int32_t sxe2_repr_dev_start(struct rte_eth_dev *dev)
53 : : {
54 : 0 : int32_t ret = 0;
55 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
56 : 0 : PMD_INIT_FUNC_TRACE();
57 : :
58 : 0 : ret = sxe2_queues_init(dev);
59 [ # # ]: 0 : if (ret) {
60 : 0 : PMD_LOG_ERR(INIT, "Failed to init queues.");
61 : 0 : goto l_end;
62 : : }
63 : :
64 : 0 : sxe2_rx_mode_func_set(dev);
65 : 0 : sxe2_tx_mode_func_set(dev);
66 : :
67 : 0 : ret = sxe2_link_update_init(dev);
68 [ # # ]: 0 : if (ret) {
69 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize link update, ret:%d", ret);
70 : 0 : goto l_end;
71 : : }
72 : :
73 : 0 : ret = sxe2_repr_rxq_intr_enable(dev);
74 [ # # ]: 0 : if (ret) {
75 : 0 : PMD_LOG_ERR(INIT, "Failed to enable rx queue intr");
76 : 0 : goto l_end;
77 : : }
78 : :
79 : 0 : ret = sxe2_queues_start(dev);
80 [ # # ]: 0 : if (ret) {
81 : 0 : PMD_LOG_ERR(INIT, "enable queues failed");
82 : 0 : goto l_start_queues_err;
83 : : }
84 : :
85 : 0 : dev->data->dev_started = 1;
86 : 0 : adapter->started = 1;
87 : 0 : goto l_end;
88 : 0 : l_start_queues_err:
89 : 0 : (void)sxe2_rxq_intr_disable(dev);
90 : 0 : l_end:
91 : 0 : return ret;
92 : : }
93 : :
94 : 0 : static int32_t sxe2_repr_dev_stop(struct rte_eth_dev *dev)
95 : : {
96 : 0 : int32_t ret = 0;
97 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
98 : 0 : PMD_INIT_FUNC_TRACE();
99 : :
100 [ # # ]: 0 : if (adapter->started == 0)
101 : 0 : goto l_end;
102 : :
103 : 0 : sxe2_repr_rxq_intr_disable(dev);
104 : :
105 : 0 : sxe2_txqs_all_stop(dev);
106 : 0 : sxe2_rxqs_all_stop(dev);
107 : :
108 : 0 : dev->data->dev_started = 0;
109 : 0 : adapter->started = 0;
110 : 0 : l_end:
111 : 0 : return ret;
112 : : }
113 : :
114 : 0 : static int32_t sxe2_repr_dev_close(struct rte_eth_dev *dev)
115 : : {
116 : 0 : PMD_DEV_LOG_INFO(SXE2_DEV_PRIVATE_TO_ADAPTER(dev),
117 : : INIT, "repr close");
118 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
119 : 0 : sxe2_mp_uninit(dev);
120 : 0 : goto l_end;
121 : : }
122 : 0 : (void)sxe2_repr_dev_stop(dev);
123 : 0 : (void)sxe2_queues_release(dev);
124 : 0 : sxe2_mp_uninit(dev);
125 : 0 : sxe2_repr_dev_uinit(dev);
126 : 0 : l_end:
127 : 0 : return 0;
128 : : }
129 : :
130 : 0 : static int32_t sxe2_repr_dev_infos_get(__rte_unused struct rte_eth_dev *dev,
131 : : struct rte_eth_dev_info *dev_info)
132 : : {
133 : 0 : dev_info->max_rx_queues = 1;
134 : 0 : dev_info->max_tx_queues = 1;
135 : 0 : dev_info->min_rx_bufsize = SXE2_MIN_BUF_SIZE;
136 : 0 : dev_info->max_rx_pktlen = SXE2_FRAME_SIZE_MAX;
137 : 0 : dev_info->max_lro_pkt_size = SXE2_FRAME_SIZE_MAX * SXE2_RX_LRO_DESC_MAX_NUM;
138 : 0 : dev_info->max_mtu = dev_info->max_rx_pktlen - SXE2_ETH_OVERHEAD;
139 : 0 : dev_info->min_mtu = RTE_ETHER_MIN_MTU;
140 : 0 : dev_info->max_mac_addrs = SXE2_NUM_MACADDR_MAX;
141 : :
142 : 0 : dev_info->rx_offload_capa =
143 : : RTE_ETH_RX_OFFLOAD_KEEP_CRC |
144 : : RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
145 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
146 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
147 : : RTE_ETH_RX_OFFLOAD_SCTP_CKSUM |
148 : : RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM;
149 : 0 : dev_info->tx_offload_capa =
150 : : RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
151 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
152 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
153 : : RTE_ETH_TX_OFFLOAD_SCTP_CKSUM |
154 : : RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM |
155 : : RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM;
156 : :
157 : 0 : dev_info->tx_queue_offload_capa = RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
158 : :
159 : 0 : dev_info->default_rxconf = (struct rte_eth_rxconf) {
160 : : .rx_thresh = {
161 : : .pthresh = SXE2_DEFAULT_RX_PTHRESH,
162 : : .hthresh = SXE2_DEFAULT_RX_HTHRESH,
163 : : .wthresh = SXE2_DEFAULT_RX_WTHRESH,
164 : : },
165 : : .rx_free_thresh = SXE2_DEFAULT_RX_FREE_THRESH,
166 : : .rx_drop_en = 0,
167 : : .offloads = 0,
168 : : };
169 : :
170 : 0 : dev_info->default_txconf = (struct rte_eth_txconf) {
171 : : .tx_thresh = {
172 : : .pthresh = SXE2_DEFAULT_TX_PTHRESH,
173 : : .hthresh = SXE2_DEFAULT_TX_HTHRESH,
174 : : .wthresh = SXE2_DEFAULT_TX_WTHRESH,
175 : : },
176 : : .tx_free_thresh = SXE2_DEFAULT_TX_FREE_THRESH,
177 : : .tx_rs_thresh = SXE2_DEFAULT_TX_RSBIT_THRESH,
178 : : .offloads = 0,
179 : : };
180 : :
181 : 0 : dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
182 : : .nb_max = SXE2_MAX_RING_DESC,
183 : : .nb_min = SXE2_MIN_RING_DESC,
184 : : .nb_align = SXE2_ALIGN,
185 : : };
186 : :
187 : 0 : dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
188 : : .nb_max = SXE2_MAX_RING_DESC,
189 : : .nb_min = SXE2_MIN_RING_DESC,
190 : : .nb_align = SXE2_ALIGN,
191 : : .nb_mtu_seg_max = SXE2_TX_MTU_SEG_MAX,
192 : : .nb_seg_max = SXE2_MAX_RING_DESC,
193 : : };
194 : :
195 : 0 : dev_info->speed_capa = RTE_ETH_LINK_SPEED_10G | RTE_ETH_LINK_SPEED_25G |
196 : : RTE_ETH_LINK_SPEED_50G | RTE_ETH_LINK_SPEED_100G;
197 : :
198 : :
199 : 0 : dev_info->default_rxportconf.burst_size = SXE2_RX_MAX_BURST;
200 : 0 : dev_info->default_txportconf.burst_size = SXE2_TX_MAX_BURST;
201 : 0 : dev_info->default_rxportconf.nb_queues = 1;
202 : 0 : dev_info->default_txportconf.nb_queues = 1;
203 : 0 : dev_info->default_rxportconf.ring_size = SXE2_RING_SIZE_MIN;
204 : 0 : dev_info->default_txportconf.ring_size = SXE2_RING_SIZE_MIN;
205 : :
206 : 0 : dev_info->rx_seg_capa.offset_allowed = false;
207 : :
208 : 0 : dev_info->rx_seg_capa.offset_align_log2 = false;
209 : :
210 : 0 : return 0;
211 : : }
212 : :
213 : : static const struct eth_dev_ops sxe2_switchdev_repr_dev_ops = {
214 : : .dev_configure = sxe2_repr_dev_configure,
215 : :
216 : : .dev_start = sxe2_repr_dev_start,
217 : : .dev_stop = sxe2_repr_dev_stop,
218 : :
219 : : .rx_queue_start = sxe2_rx_queue_start,
220 : : .rx_queue_stop = sxe2_rx_queue_stop,
221 : : .tx_queue_start = sxe2_tx_queue_start,
222 : : .tx_queue_stop = sxe2_tx_queue_stop,
223 : : .rx_queue_setup = sxe2_rx_queue_setup,
224 : : .rx_queue_release = sxe2_rx_queue_release,
225 : : .tx_queue_setup = sxe2_tx_queue_setup,
226 : : .tx_queue_release = sxe2_tx_queue_release,
227 : :
228 : : .dev_close = sxe2_repr_dev_close,
229 : : .dev_infos_get = sxe2_repr_dev_infos_get,
230 : : .dev_supported_ptypes_get = sxe2_dev_supported_ptypes_get,
231 : : .link_update = sxe2_link_update,
232 : :
233 : : .promiscuous_enable = sxe2_repr_promisc_enable,
234 : : .promiscuous_disable = sxe2_repr_promisc_disable,
235 : : .allmulticast_enable = sxe2_repr_allmulti_enable,
236 : : .allmulticast_disable = sxe2_repr_allmulti_disable,
237 : :
238 : : .eth_dev_priv_dump = sxe2_eth_dev_priv_dump,
239 : :
240 : : .stats_get = sxe2_stats_info_get,
241 : : .stats_reset = sxe2_stats_info_reset,
242 : : .xstats_get = sxe2_xstats_info_get,
243 : : .xstats_get_names = sxe2_xstats_names_get,
244 : : .xstats_reset = sxe2_stats_info_reset,
245 : : };
246 : :
247 : 0 : void sxe2_repr_all_close(struct rte_eth_dev *dev)
248 : : {
249 : 0 : uint16_t vf_id;
250 : 0 : struct rte_eth_dev *repr_eth_dev = NULL;
251 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
252 : :
253 [ # # ]: 0 : if (adapter->repr_ctxt.nb_repr_vf) {
254 [ # # ]: 0 : for (vf_id = 0; vf_id < adapter->repr_ctxt.nb_repr_vf; vf_id++) {
255 : 0 : repr_eth_dev = adapter->repr_ctxt.vf_rep_eth_dev[vf_id];
256 [ # # # # ]: 0 : if (!repr_eth_dev || repr_eth_dev->data->dev_started == 0)
257 : 0 : continue;
258 : :
259 : 0 : (void)rte_eth_dev_stop(repr_eth_dev->data->port_id);
260 : 0 : (void)rte_eth_dev_close(repr_eth_dev->data->port_id);
261 : : }
262 : : }
263 : 0 : }
264 : :
265 : 0 : static void sxe2_repr_adapter_init(struct rte_eth_dev *dev_repr,
266 : : struct sxe2_adapter *parent_adapter,
267 : : uint16_t repr_id)
268 : : {
269 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev_repr);
270 : :
271 : 0 : dev_repr->data->backer_port_id = parent_adapter->dev_port_id;
272 : 0 : dev_repr->data->representor_id = repr_id;
273 : 0 : dev_repr->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
274 : :
275 : 0 : adapter->is_dev_repr = true;
276 : 0 : adapter->dev_port_id = dev_repr->data->port_id;
277 : 0 : adapter->dev_type = parent_adapter->dev_type;
278 : 0 : adapter->switchdev_info.is_switchdev = parent_adapter->switchdev_info.is_switchdev;
279 : 0 : adapter->port_idx = parent_adapter->port_idx;
280 : 0 : adapter->pf_idx = parent_adapter->pf_idx;
281 : 0 : adapter->dev_info.pci = parent_adapter->dev_info.pci;
282 : 0 : adapter->dev_info.fw = parent_adapter->dev_info.fw;
283 : 0 : }
284 : :
285 : 0 : static int32_t sxe2_repr_eth_init(struct rte_eth_dev *dev)
286 : : {
287 : 0 : int32_t ret = 0;
288 : :
289 : 0 : ret = sxe2_filter_init(dev);
290 [ # # ]: 0 : if (ret) {
291 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize l2 filter, ret:%d", ret);
292 : 0 : goto l_end;
293 : : }
294 : 0 : ret = sxe2_link_update_init(dev);
295 [ # # ]: 0 : if (ret) {
296 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize link update, ret:%d", ret);
297 : 0 : goto l_end;
298 : : }
299 : :
300 : 0 : ret = sxe2_mac_addr_init(dev);
301 [ # # ]: 0 : if (ret != 0) {
302 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize mac address, ret:%d", ret);
303 : 0 : goto l_end;
304 : : }
305 : :
306 : 0 : l_end:
307 : 0 : return ret;
308 : : }
309 : :
310 : 0 : static int32_t sxe2_repr_dev_pci_map_init(struct rte_eth_dev *dev)
311 : : {
312 : 0 : struct sxe2_adapter *rep_adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
313 : 0 : struct sxe2_pci_map_context *map_ctxt = &rep_adapter->map_ctxt;
314 : 0 : struct sxe2_pci_map_bar_info *bar_info = NULL;
315 : 0 : struct sxe2_pci_map_segment_info *seg_info = NULL;
316 : 0 : uint16_t txq_cnt = rep_adapter->q_ctxt.qp_cnt_assign;
317 : 0 : uint16_t txq_base = rep_adapter->q_ctxt.base_idx_in_pf;
318 : 0 : uint16_t rxq_cnt = rep_adapter->q_ctxt.qp_cnt_assign;
319 : 0 : uint16_t rxq_base = rep_adapter->q_ctxt.base_idx_in_pf;
320 : 0 : uint16_t irq_cnt = rep_adapter->irq_ctxt.max_cnt_hw;
321 : 0 : uint16_t irq_base = rep_adapter->irq_ctxt.base_idx_in_func;
322 : 0 : int32_t ret = 0;
323 : :
324 : 0 : PMD_INIT_FUNC_TRACE();
325 : :
326 : 0 : rep_adapter->dev_info.dev_data = dev->data;
327 : :
328 : 0 : map_ctxt->bar_cnt = 2;
329 : :
330 : 0 : bar_info = rte_zmalloc("repr_bar_info",
331 : : sizeof(struct sxe2_pci_map_bar_info) * map_ctxt->bar_cnt, 0);
332 [ # # ]: 0 : if (bar_info == NULL) {
333 : 0 : PMD_LOG_ERR(INIT, "Failed to alloc bar_info");
334 : 0 : ret = -ENOMEM;
335 : 0 : goto l_end;
336 : : }
337 : 0 : bar_info[0].bar_idx = 0;
338 : 0 : bar_info[0].map_cnt = SXE2_PCI_MAP_RES_MAX_COUNT;
339 : 0 : seg_info = rte_zmalloc("repr_seg_info_bar0",
340 : : sizeof(struct sxe2_pci_map_segment_info) * bar_info[0].map_cnt, 0);
341 [ # # ]: 0 : if (seg_info == NULL) {
342 : 0 : PMD_LOG_ERR(INIT, "Failed to alloc seg_info");
343 : 0 : ret = -ENOMEM;
344 : 0 : goto l_free_bar;
345 : : }
346 : :
347 : 0 : bar_info[0].seg_info = seg_info;
348 : :
349 : 0 : bar_info[1].bar_idx = 4;
350 : 0 : bar_info[1].map_cnt = SXE2_PCI_MAP_RES_MAX_COUNT;
351 : 0 : seg_info = rte_zmalloc("repr_seg_info_bar4",
352 : : sizeof(struct sxe2_pci_map_segment_info) * bar_info[1].map_cnt,
353 : : 0);
354 [ # # ]: 0 : if (!seg_info) {
355 : 0 : PMD_LOG_ERR(INIT, "Failed to alloc seg_info");
356 : 0 : ret = -ENOMEM;
357 : 0 : goto l_free_seg0;
358 : : }
359 : :
360 : 0 : bar_info[1].seg_info = seg_info;
361 : 0 : map_ctxt->bar_info = bar_info;
362 : :
363 : 0 : map_ctxt->addr_info = sxe2_net_map_addr_info_repr;
364 : :
365 : 0 : ret = sxe2_dev_pci_res_seg_map(rep_adapter, SXE2_PCI_MAP_RES_DOORBELL_TX,
366 : : txq_cnt, txq_base);
367 [ # # ]: 0 : if (ret != 0) {
368 : 0 : PMD_LOG_ERR(INIT, "Failed to map txq doorbell addr, ret=%d", ret);
369 : 0 : goto l_free_seg1;
370 : : }
371 : :
372 : 0 : ret = sxe2_dev_pci_res_seg_map(rep_adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL,
373 : : rxq_cnt, rxq_base);
374 [ # # ]: 0 : if (ret != 0) {
375 : 0 : PMD_LOG_ERR(INIT, "Failed to map rxq tail doorbell addr, ret=%d", ret);
376 : 0 : goto l_free_txq;
377 : : }
378 : :
379 : 0 : ret = sxe2_dev_pci_res_seg_map(rep_adapter, SXE2_PCI_MAP_RES_IRQ_DYN,
380 : : irq_cnt, irq_base);
381 [ # # ]: 0 : if (ret != 0) {
382 : 0 : PMD_LOG_ERR(INIT, "Failed to map irq dyn addr, ret=%d", ret);
383 : 0 : goto l_free_rxq_tail;
384 : : }
385 : :
386 : 0 : ret = sxe2_dev_pci_res_seg_map(rep_adapter, SXE2_PCI_MAP_RES_IRQ_ITR,
387 : : irq_cnt, irq_base);
388 [ # # ]: 0 : if (ret != 0) {
389 : 0 : PMD_LOG_ERR(INIT, "Failed to map irq itr addr, ret=%d", ret);
390 : 0 : goto l_free_irq_dyn;
391 : : }
392 : :
393 : 0 : ret = sxe2_dev_pci_res_seg_map(rep_adapter, SXE2_PCI_MAP_RES_IRQ_MSIX,
394 : : irq_cnt, irq_base);
395 [ # # ]: 0 : if (ret != 0) {
396 : 0 : PMD_LOG_ERR(INIT, "Failed to map irq msix addr, ret=%d", ret);
397 : 0 : goto l_free_irq_itr;
398 : : }
399 : 0 : goto l_end;
400 : :
401 : 0 : l_free_irq_itr:
402 : 0 : (void)sxe2_dev_pci_seg_unmap(rep_adapter, SXE2_PCI_MAP_RES_IRQ_ITR);
403 : 0 : l_free_irq_dyn:
404 : 0 : (void)sxe2_dev_pci_seg_unmap(rep_adapter, SXE2_PCI_MAP_RES_IRQ_DYN);
405 : 0 : l_free_rxq_tail:
406 : 0 : (void)sxe2_dev_pci_seg_unmap(rep_adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL);
407 : 0 : l_free_txq:
408 : 0 : (void)sxe2_dev_pci_seg_unmap(rep_adapter, SXE2_PCI_MAP_RES_DOORBELL_TX);
409 : 0 : l_free_seg1:
410 [ # # ]: 0 : if (bar_info[1].seg_info) {
411 : 0 : rte_free(bar_info[1].seg_info);
412 : 0 : bar_info[1].seg_info = NULL;
413 : : }
414 : 0 : l_free_seg0:
415 [ # # ]: 0 : if (bar_info[0].seg_info) {
416 : 0 : rte_free(bar_info[0].seg_info);
417 : 0 : bar_info[0].seg_info = NULL;
418 : : }
419 : 0 : l_free_bar:
420 : 0 : if (bar_info) {
421 : 0 : rte_free(bar_info);
422 : 0 : bar_info = NULL;
423 : : }
424 : 0 : l_end:
425 : 0 : return ret;
426 : : }
427 : :
428 : 0 : int32_t sxe2_repr_dev_init(struct rte_eth_dev *dev,
429 : : struct sxe2_adapter *parent_adapter,
430 : : uint16_t repr_id)
431 : : {
432 : 0 : int32_t ret = 0;
433 : :
434 : 0 : PMD_INIT_FUNC_TRACE();
435 : :
436 : 0 : sxe2_set_common_function(dev);
437 : :
438 : 0 : sxe2_repr_adapter_init(dev, parent_adapter, repr_id);
439 : :
440 : 0 : dev->dev_ops = &sxe2_switchdev_repr_dev_ops;
441 : :
442 : 0 : ret = sxe2_vsi_repr_main_vsi_create(dev, parent_adapter, repr_id);
443 [ # # ]: 0 : if (ret) {
444 : 0 : PMD_LOG_ERR(INIT, "Failed to create representor main vsi, ret=[%d]", ret);
445 : 0 : goto l_end;
446 : : }
447 : :
448 : 0 : ret = sxe2_switchdev_repr_private_data_init(dev, parent_adapter, repr_id);
449 [ # # ]: 0 : if (ret) {
450 : 0 : PMD_LOG_ERR(INIT, "Failed to fill representor private data, ret=[%d]", ret);
451 : 0 : goto l_init_priv_data_err;
452 : : }
453 : :
454 : 0 : ret = sxe2_repr_dev_pci_map_init(dev);
455 [ # # ]: 0 : if (ret) {
456 : 0 : PMD_LOG_ERR(INIT, "Failed to pci addr map, ret=[%d]", ret);
457 : 0 : goto l_init_pci_error;
458 : : }
459 : :
460 : 0 : ret = sxe2_switchdev_dev_info_init(dev, parent_adapter);
461 [ # # ]: 0 : if (ret) {
462 : 0 : PMD_LOG_ERR(INIT, "Failed to get device info, ret=[%d]", ret);
463 : 0 : goto l_init_dev_info_err;
464 : : }
465 : :
466 : 0 : ret = sxe2_flow_init(dev);
467 [ # # ]: 0 : if (ret) {
468 : 0 : PMD_LOG_ERR(INIT, "Failed to init flow, ret=%d", ret);
469 : 0 : goto l_init_flow_err;
470 : : }
471 : :
472 : 0 : ret = sxe2_repr_eth_init(dev);
473 [ # # ]: 0 : if (ret) {
474 : 0 : PMD_LOG_ERR(INIT, "Failed to init device, status = %d", ret);
475 : 0 : goto l_init_eth_err;
476 : : }
477 : :
478 : 0 : ret = sxe2_sw_irq_ctxt_init(dev);
479 [ # # ]: 0 : if (ret) {
480 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize sw parameters, ret=[%d]", ret);
481 : 0 : goto l_init_sw_err;
482 : : }
483 : :
484 : 0 : ret = sxe2_stats_init(dev);
485 [ # # ]: 0 : if (ret) {
486 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize stats, ret=[%d]", ret);
487 : 0 : goto l_init_irq_ctxt_err;
488 : : }
489 : :
490 : 0 : goto l_end;
491 : :
492 : 0 : l_init_irq_ctxt_err:
493 : 0 : sxe2_sw_irq_ctxt_uninit(dev);
494 : 0 : l_init_sw_err:
495 : 0 : sxe2_eth_uinit(dev);
496 : 0 : l_init_eth_err:
497 : 0 : (void)sxe2_flow_uninit(dev);
498 : 0 : l_init_flow_err:
499 : 0 : l_init_dev_info_err:
500 : 0 : sxe2_dev_pci_map_uinit(dev);
501 : 0 : l_init_pci_error:
502 : 0 : (void)sxe2_switchdev_uninit(dev);
503 : 0 : l_init_priv_data_err:
504 : 0 : sxe2_vsi_repr_main_vsi_destroy(dev);
505 : 0 : l_end:
506 : 0 : return ret;
507 : : }
508 : :
509 : 0 : static void sxe2_repr_dev_uinit(struct rte_eth_dev *dev)
510 : : {
511 : 0 : sxe2_eth_uinit(dev);
512 : 0 : (void)sxe2_flow_uninit(dev);
513 : 0 : sxe2_dev_pci_map_uinit(dev);
514 : 0 : (void)sxe2_switchdev_uninit(dev);
515 : 0 : sxe2_vsi_repr_main_vsi_destroy(dev);
516 : 0 : }
517 : :
518 : 0 : int32_t sxe2_switchdev_repr_devs_init(struct sxe2_adapter *adapter,
519 : : struct rte_eth_devargs *req_eth_da)
520 : : {
521 : 0 : struct rte_eth_dev *eth_dev = NULL;
522 : 0 : int32_t ret;
523 : 0 : uint16_t repr_idx = 0, tmp_repr_idx = 0;
524 : 0 : char name[RTE_ETH_NAME_MAX_LEN];
525 : :
526 [ # # ]: 0 : if (req_eth_da->nb_representor_ports == 0) {
527 : 0 : ret = 0;
528 : 0 : goto l_end;
529 : : }
530 : :
531 [ # # ]: 0 : if (req_eth_da->nb_representor_ports > adapter->repr_ctxt.nb_vf) {
532 : 0 : PMD_LOG_ERR(INIT, "Failed to create repr vsi, nb_representor_ports=%d, nb_vf=%d",
533 : : req_eth_da->nb_representor_ports, adapter->repr_ctxt.nb_vf);
534 : 0 : ret = -EINVAL;
535 : 0 : goto l_end;
536 : : }
537 : :
538 : 0 : ret = sxe2_other_vsi_create(adapter, req_eth_da->nb_representor_ports);
539 [ # # ]: 0 : if (ret) {
540 : 0 : PMD_LOG_ERR(INIT, "Failed to create representor vsi, ret=%d", ret);
541 : 0 : goto l_release_port;
542 : : }
543 : :
544 : 0 : adapter->repr_ctxt.vf_rep_eth_dev = rte_zmalloc("sxe2_repr_ethdev",
545 : 0 : req_eth_da->nb_representor_ports * sizeof(struct rte_eth_dev *), 0);
546 [ # # ]: 0 : if (adapter->repr_ctxt.vf_rep_eth_dev == NULL) {
547 : 0 : PMD_LOG_ERR(INIT, "Failed to malloc representor eth dev.");
548 : 0 : ret = -ENOMEM;
549 : 0 : goto l_release_port;
550 : : }
551 : :
552 [ # # ]: 0 : for (repr_idx = 0; repr_idx < req_eth_da->nb_representor_ports; ++repr_idx) {
553 : 0 : snprintf(name, sizeof(name), "%s_representor_vf%u",
554 : 0 : adapter->cdev->dev->name,
555 : 0 : req_eth_da->representor_ports[repr_idx]);
556 : :
557 : 0 : eth_dev = rte_eth_dev_allocate(name);
558 [ # # ]: 0 : if (!eth_dev) {
559 : 0 : ret = -ENOMEM;
560 : 0 : goto l_release_port;
561 : : }
562 : 0 : eth_dev->data->numa_node = adapter->dev_info.dev_data->numa_node;
563 : 0 : eth_dev->data->dev_private = rte_zmalloc_socket(name,
564 : : sizeof(struct sxe2_adapter),
565 : : RTE_CACHE_LINE_SIZE,
566 : : eth_dev->data->numa_node);
567 : :
568 [ # # ]: 0 : if (!eth_dev->data->dev_private) {
569 : 0 : rte_eth_dev_release_port(eth_dev);
570 : 0 : ret = -ENOMEM;
571 : 0 : goto l_release_port;
572 : : }
573 : :
574 : 0 : eth_dev->device = rte_eth_devices[adapter->dev_info.dev_data->port_id].device;
575 : :
576 : 0 : ret = sxe2_repr_dev_init(eth_dev, adapter,
577 : 0 : req_eth_da->representor_ports[repr_idx]);
578 [ # # ]: 0 : if (ret) {
579 : 0 : PMD_LOG_ERR(INIT, "Sxe2 dev init failed, ret=%d", ret);
580 : 0 : rte_eth_dev_release_port(eth_dev);
581 : 0 : goto l_release_port;
582 : : }
583 : :
584 : 0 : eth_dev->intr_handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_SHARED);
585 [ # # ]: 0 : if (eth_dev->intr_handle == NULL) {
586 : 0 : PMD_LOG_ERR(INIT, "Sxe2 dev init representor intr_handle failed");
587 : 0 : ret = -ENOMEM;
588 : 0 : sxe2_repr_dev_uinit(eth_dev);
589 : 0 : rte_eth_dev_release_port(eth_dev);
590 : 0 : goto l_release_port;
591 : : }
592 : 0 : adapter->repr_ctxt.vf_rep_eth_dev[repr_idx] = eth_dev;
593 : 0 : rte_eth_dev_probing_finish(eth_dev);
594 : : }
595 : 0 : adapter->repr_ctxt.nb_repr_vf = req_eth_da->nb_representor_ports;
596 : 0 : goto l_end;
597 : :
598 : 0 : l_release_port:
599 [ # # ]: 0 : for (tmp_repr_idx = 0; tmp_repr_idx < repr_idx; ++tmp_repr_idx) {
600 : 0 : struct rte_eth_dev *rep_dev = adapter->repr_ctxt.vf_rep_eth_dev[tmp_repr_idx];
601 [ # # ]: 0 : if (rep_dev) {
602 : 0 : sxe2_repr_dev_uinit(rep_dev);
603 : 0 : rte_intr_instance_free(rep_dev->intr_handle);
604 : 0 : rte_eth_dev_release_port(rep_dev);
605 : 0 : adapter->repr_ctxt.vf_rep_eth_dev[tmp_repr_idx] = NULL;
606 : : }
607 : : }
608 : :
609 : 0 : rte_free(adapter->repr_ctxt.vf_rep_eth_dev);
610 : 0 : adapter->repr_ctxt.vf_rep_eth_dev = NULL;
611 : :
612 : 0 : l_end:
613 : 0 : return ret;
614 : : }
|