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 <rte_string_fns.h>
6 : : #include <ethdev_pci.h>
7 : : #include <ctype.h>
8 : : #include <sys/types.h>
9 : : #include <sys/stat.h>
10 : : #include <unistd.h>
11 : : #include <rte_tailq.h>
12 : : #include <rte_version.h>
13 : : #include <bus_pci_driver.h>
14 : : #include <dev_driver.h>
15 : : #include <ethdev_driver.h>
16 : : #include <rte_ethdev.h>
17 : : #include <rte_alarm.h>
18 : : #include <rte_dev_info.h>
19 : : #include <rte_pci.h>
20 : : #include <rte_mbuf_dyn.h>
21 : : #include <rte_cycles.h>
22 : : #include <rte_eal_paging.h>
23 : :
24 : : #include "sxe2_ethdev.h"
25 : : #include "sxe2_irq.h"
26 : : #include "sxe2_drv_cmd.h"
27 : : #include "sxe2_cmd_chnl.h"
28 : : #include "sxe2_tx.h"
29 : : #include "sxe2_rx.h"
30 : : #include "sxe2_txrx.h"
31 : : #include "sxe2_mac.h"
32 : : #include "sxe2_common.h"
33 : : #include "sxe2_common_log.h"
34 : : #include "sxe2_mp.h"
35 : : #include "sxe2_flow.h"
36 : : #include "sxe2_stats.h"
37 : : #include "sxe2_host_regs.h"
38 : : #include "sxe2_switchdev.h"
39 : : #include "sxe2_ioctl_chnl_func.h"
40 : : #include "sxe2_dump.h"
41 : : #include "sxe2_ethdev_repr.h"
42 : : #include "sxe2vf_regs.h"
43 : : #include "sxe2_msg.h"
44 : :
45 : : #define SXE2_PCI_VENDOR_ID_1 0x1ff2
46 : : #define SXE2_PCI_DEVICE_ID_PF_1 0x10b1
47 : : #define SXE2_PCI_DEVICE_ID_VF_1 0x10b
48 : :
49 : : #define SXE2_PCI_VENDOR_ID_2 0x1d94
50 : : #define SXE2_PCI_DEVICE_ID_PF_2 0x1260
51 : : #define SXE2_PCI_DEVICE_ID_VF_2 0x126f
52 : :
53 : : #define SXE2_PCI_DEVICE_ID_PF_3 0x10b3
54 : : #define SXE2_PCI_DEVICE_ID_VF_3 0x10b4
55 : :
56 : : #define SXE2_PCI_VENDOR_ID_206F 0x206f
57 : :
58 : : static const struct rte_pci_id pci_id_sxe2_tbl[] = {
59 : : { RTE_PCI_DEVICE(SXE2_PCI_VENDOR_ID_1, SXE2_PCI_DEVICE_ID_PF_1)},
60 : : { RTE_PCI_DEVICE(SXE2_PCI_VENDOR_ID_1, SXE2_PCI_DEVICE_ID_VF_1)},
61 : : { RTE_PCI_DEVICE(SXE2_PCI_VENDOR_ID_2, SXE2_PCI_DEVICE_ID_PF_2)},
62 : : { RTE_PCI_DEVICE(SXE2_PCI_VENDOR_ID_2, SXE2_PCI_DEVICE_ID_VF_2)},
63 : : { RTE_PCI_DEVICE(SXE2_PCI_VENDOR_ID_1, SXE2_PCI_DEVICE_ID_PF_3)},
64 : : { RTE_PCI_DEVICE(SXE2_PCI_VENDOR_ID_1, SXE2_PCI_DEVICE_ID_VF_3)},
65 : : { RTE_PCI_DEVICE(SXE2_PCI_VENDOR_ID_206F, SXE2_PCI_DEVICE_ID_PF_1)},
66 : : { RTE_PCI_DEVICE(SXE2_PCI_VENDOR_ID_206F, SXE2_PCI_DEVICE_ID_VF_1)},
67 : : { .vendor_id = 0, },
68 : : };
69 : :
70 : : #define SXE2_TXSCH_NODE_ADJ_LVL_MAX 3
71 : :
72 : : #define SXE2_DEVARG_FLOW_DUP_PATTERN_MODE "flow-duplicate-pattern"
73 : : #define SXE2_DEVARG_FUNC_FLOW_DIRCT "function-flow-direct"
74 : : #define SXE2_DEVARG_FNAV_STAT_TYPE "fnav-stat-type"
75 : : #define SXE2_DEVARG_NO_SCHED_MODE "no-sched-mode"
76 : : #define SXE2_DEVARG_SCHED_LAYER_MODE "sched-layer-mode"
77 : : #define SXE2_DEVARG_RX_LOW_LATENCY "rx-low-latency"
78 : :
79 : : static struct sxe2_pci_map_addr_info sxe2_net_map_addr_info_pf[SXE2_PCI_MAP_RES_MAX_COUNT] = {
80 : : [SXE2_PCI_MAP_RES_INVALID] = {.addr_base = 0,
81 : : .bar_idx = 0,
82 : : .reg_width = 0},
83 : : [SXE2_PCI_MAP_RES_DOORBELL_TX] = {.addr_base = SXE2_TXQ_LEGACY_DBLL(0),
84 : : .bar_idx = 0,
85 : : .reg_width = 4},
86 : : [SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL] = {.addr_base = SXE2_RXQ_TAIL(0),
87 : : .bar_idx = 0,
88 : : .reg_width = 4},
89 : : [SXE2_PCI_MAP_RES_IRQ_DYN] = {.addr_base = SXE2_VF_DYN_CTL(0),
90 : : .bar_idx = 0,
91 : : .reg_width = 4},
92 : : [SXE2_PCI_MAP_RES_IRQ_ITR] = {.addr_base = SXE2_VF_INT_ITR(0, 0),
93 : : .bar_idx = 0,
94 : : .reg_width = 4},
95 : : [SXE2_PCI_MAP_RES_IRQ_MSIX] = {.addr_base = SXE2_BAR4_MSIX_CTL(0),
96 : : .bar_idx = 4,
97 : : .reg_width = 10},
98 : : };
99 : :
100 : : static struct sxe2_pci_map_addr_info sxe2_net_map_addr_info_vf[SXE2_PCI_MAP_RES_MAX_COUNT] = {
101 : : [SXE2_PCI_MAP_RES_INVALID] = {.addr_base = 0,
102 : : .bar_idx = 0,
103 : : .reg_width = 0},
104 : : [SXE2_PCI_MAP_RES_DOORBELL_TX] = {.addr_base = SXE2VF_TXQ_TAIL(0),
105 : : .bar_idx = 0,
106 : : .reg_width = 4},
107 : : [SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL] = {.addr_base = SXE2VF_RXQ_TAIL(0),
108 : : .bar_idx = 0,
109 : : .reg_width = 4},
110 : : [SXE2_PCI_MAP_RES_IRQ_DYN] = {.addr_base = SXE2VF_VF_DYN_CTL(0),
111 : : .bar_idx = 0,
112 : : .reg_width = 4},
113 : : [SXE2_PCI_MAP_RES_IRQ_ITR] = {.addr_base = SXE2VF_VF_INT_ITR(0, 0),
114 : : .bar_idx = 0,
115 : : .reg_width = 4},
116 : : [SXE2_PCI_MAP_RES_IRQ_MSIX] = {.addr_base = SXE2VF_BAR4_MSIX_CTL(0),
117 : : .bar_idx = 4,
118 : : .reg_width = 0x10},
119 : : };
120 : :
121 : : static int32_t sxe2_dev_configure(struct rte_eth_dev *dev);
122 : : static int32_t sxe2_dev_start(struct rte_eth_dev *dev);
123 : : static int32_t sxe2_dev_stop(struct rte_eth_dev *dev);
124 : : static int32_t sxe2_dev_close(struct rte_eth_dev *dev);
125 : : static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info);
126 : : static const uint32_t *sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev
127 : : __rte_unused, size_t *no_of_elements __rte_unused);
128 : : static int32_t sxe2_udp_tunnel_port_add(struct rte_eth_dev *dev,
129 : : struct rte_eth_udp_tunnel *tunnel_udp);
130 : : static int32_t sxe2_udp_tunnel_port_del(struct rte_eth_dev *dev,
131 : : struct rte_eth_udp_tunnel *tunnel_udp);
132 : : static int32_t sxe2_fw_version_string_get(struct rte_eth_dev *dev,
133 : : char *fw_version, size_t fw_size);
134 : : static int32_t sxe2_get_module_info(struct rte_eth_dev *dev,
135 : : struct rte_eth_dev_module_info *info);
136 : : static int32_t sxe2_get_module_eeprom(struct rte_eth_dev *dev,
137 : : struct rte_dev_eeprom_info *info);
138 : :
139 : : static const struct eth_dev_ops sxe2_eth_dev_ops = {
140 : : .dev_configure = sxe2_dev_configure,
141 : : .dev_start = sxe2_dev_start,
142 : : .dev_stop = sxe2_dev_stop,
143 : : .dev_close = sxe2_dev_close,
144 : : .dev_infos_get = sxe2_dev_infos_get,
145 : : .dev_supported_ptypes_get = sxe2_dev_supported_ptypes_get,
146 : : .link_update = sxe2_link_update,
147 : :
148 : : .rx_queue_start = sxe2_rx_queue_start,
149 : : .rx_queue_stop = sxe2_rx_queue_stop,
150 : : .tx_queue_start = sxe2_tx_queue_start,
151 : : .tx_queue_stop = sxe2_tx_queue_stop,
152 : : .rx_queue_setup = sxe2_rx_queue_setup,
153 : : .rx_queue_release = sxe2_rx_queue_release,
154 : : .tx_queue_setup = sxe2_tx_queue_setup,
155 : : .tx_queue_release = sxe2_tx_queue_release,
156 : : .rx_queue_intr_enable = sxe2_rx_queue_intr_enable,
157 : : .rx_queue_intr_disable = sxe2_rx_queue_intr_disable,
158 : :
159 : : .rxq_info_get = sxe2_rx_queue_info_get,
160 : : .txq_info_get = sxe2_tx_queue_info_get,
161 : : .rx_burst_mode_get = sxe2_rx_burst_mode_get,
162 : : .tx_burst_mode_get = sxe2_tx_burst_mode_get,
163 : : .tx_done_cleanup = sxe2_tx_done_cleanup,
164 : :
165 : : .promiscuous_enable = sxe2_promisc_enable,
166 : : .promiscuous_disable = sxe2_promisc_disable,
167 : : .allmulticast_enable = sxe2_allmulti_enable,
168 : : .allmulticast_disable = sxe2_allmulti_disable,
169 : :
170 : : .mac_addr_add = sxe2_mac_addr_add,
171 : : .mac_addr_remove = sxe2_mac_addr_del,
172 : : .mac_addr_set = sxe2_mac_addr_set,
173 : : .set_mc_addr_list = sxe2_set_mc_addr_list,
174 : : .mtu_set = sxe2_mtu_set,
175 : : .buffer_split_supported_hdr_ptypes_get = sxe2_buffer_split_supported_hdr_ptypes_get,
176 : :
177 : : .vlan_filter_set = sxe2_dev_vlan_filter_set,
178 : : .vlan_offload_set = sxe2_dev_vlan_offload_set,
179 : :
180 : : .reta_update = sxe2_dev_rss_reta_update,
181 : : .reta_query = sxe2_dev_rss_reta_query,
182 : : .rss_hash_update = sxe2_dev_rss_hash_update,
183 : : .rss_hash_conf_get = sxe2_dev_rss_hash_conf_get,
184 : :
185 : : .udp_tunnel_port_add = sxe2_udp_tunnel_port_add,
186 : : .udp_tunnel_port_del = sxe2_udp_tunnel_port_del,
187 : :
188 : : .flow_ops_get = sxe2_flow_ops_get,
189 : : .tm_ops_get = sxe2_tm_ops_get,
190 : :
191 : : .stats_get = sxe2_stats_info_get,
192 : : .stats_reset = sxe2_stats_info_reset,
193 : : .xstats_get = sxe2_xstats_info_get,
194 : : .xstats_get_names = sxe2_xstats_names_get,
195 : : .xstats_reset = sxe2_stats_info_reset,
196 : :
197 : : .queue_stats_mapping_set = sxe2_queue_stats_mapping_set,
198 : :
199 : : .fw_version_get = sxe2_fw_version_string_get,
200 : :
201 : : .get_monitor_addr = sxe2_get_monitor_addr,
202 : :
203 : : .get_module_info = sxe2_get_module_info,
204 : : .get_module_eeprom = sxe2_get_module_eeprom,
205 : :
206 : : .eth_dev_priv_dump = sxe2_eth_dev_priv_dump,
207 : : };
208 : :
209 : 0 : static int32_t sxe2_dev_configure(struct rte_eth_dev *dev)
210 : : {
211 : 0 : int32_t ret = 0;
212 : 0 : PMD_INIT_FUNC_TRACE();
213 : :
214 [ # # ]: 0 : if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
215 : 0 : dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
216 : :
217 : 0 : ret = sxe2_vlan_default_cfg(dev);
218 [ # # ]: 0 : if (ret) {
219 : 0 : PMD_LOG_ERR(INIT, "Failed to init vlan, ret=%d", ret);
220 : 0 : goto end;
221 : : }
222 : :
223 : 0 : ret = sxe2_rss_init(dev);
224 [ # # ]: 0 : if (ret) {
225 : 0 : PMD_LOG_ERR(INIT, "Failed to init rss, ret=%d", ret);
226 : 0 : goto end;
227 : : }
228 : :
229 : 0 : end:
230 : 0 : return ret;
231 : : }
232 : :
233 : 0 : static int32_t sxe2_dev_stop(struct rte_eth_dev *dev)
234 : : {
235 : 0 : int32_t ret = 0;
236 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
237 : 0 : PMD_INIT_FUNC_TRACE();
238 : :
239 [ # # ]: 0 : if (adapter->started == 0)
240 : 0 : goto l_end;
241 : :
242 : 0 : sxe2_rxq_intr_disable(dev);
243 : :
244 : 0 : sxe2_txqs_all_stop(dev);
245 : 0 : sxe2_rxqs_all_stop(dev);
246 : :
247 : 0 : (void)sxe2_filter_rule_stop(dev);
248 : :
249 : 0 : dev->data->dev_started = 0;
250 : 0 : adapter->started = 0;
251 : 0 : l_end:
252 : 0 : return ret;
253 : : }
254 : :
255 : 0 : static int32_t sxe2_dev_start(struct rte_eth_dev *dev)
256 : : {
257 : 0 : int32_t ret = 0;
258 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
259 : 0 : PMD_INIT_FUNC_TRACE();
260 : :
261 : 0 : ret = sxe2_flow_init_udp_tunnel_port(dev);
262 [ # # ]: 0 : if (ret) {
263 : 0 : PMD_LOG_ERR(DRV, "Failed to init udp tunnel port, ret: %d.", ret);
264 : 0 : goto l_end;
265 : : }
266 : :
267 : 0 : ret = sxe2_queues_init(dev);
268 [ # # ]: 0 : if (ret) {
269 : 0 : PMD_LOG_ERR(INIT, "Failed to init queues.");
270 : 0 : goto l_end;
271 : : }
272 : :
273 : 0 : sxe2_rx_mode_func_set(dev);
274 : 0 : sxe2_tx_mode_func_set(dev);
275 : :
276 : 0 : ret = sxe2_link_update_init(dev);
277 [ # # ]: 0 : if (ret) {
278 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize link update, ret:%d", ret);
279 : 0 : goto l_end;
280 : : }
281 : :
282 : 0 : ret = sxe2_filter_rule_start(dev);
283 [ # # ]: 0 : if (ret) {
284 : 0 : PMD_LOG_ERR(INIT, "Failed to add all mc addr to fw.");
285 : 0 : goto l_end;
286 : : }
287 : :
288 : 0 : ret = sxe2_rxq_intr_enable(dev);
289 [ # # ]: 0 : if (ret) {
290 : 0 : PMD_LOG_ERR(INIT, "Failed to enable rx queue intr");
291 : 0 : goto l_rxq_intr_err;
292 : : }
293 : :
294 : 0 : ret = sxe2_queues_start(dev);
295 [ # # ]: 0 : if (ret) {
296 : 0 : PMD_LOG_ERR(INIT, "enable queues failed");
297 : 0 : goto l_start_queues_err;
298 : : }
299 : :
300 : 0 : dev->data->dev_started = 1;
301 : 0 : adapter->started = 1;
302 : 0 : goto l_end;
303 : :
304 : 0 : l_start_queues_err:
305 : 0 : (void)sxe2_rxq_intr_disable(dev);
306 : 0 : l_rxq_intr_err:
307 : 0 : (void)sxe2_filter_rule_stop(dev);
308 : 0 : l_end:
309 : 0 : return ret;
310 : : }
311 : :
312 : 0 : static int32_t sxe2_sfp_type_get(struct sxe2_adapter *adapter, uint8_t *type)
313 : : {
314 : 0 : int32_t ret = -1;
315 : 0 : struct sxe2_sfp_read_info sfp_info;
316 : :
317 : 0 : memset(&sfp_info, 0, sizeof(sfp_info));
318 : 0 : sfp_info.bus_addr = SXE2_SFP_E2P_I2C_7BIT_ADDR0;
319 : 0 : sfp_info.len = 1;
320 : 0 : sfp_info.data = type;
321 : 0 : sfp_info.offset = 0;
322 : 0 : sfp_info.page_cnt = 0;
323 : 0 : sfp_info.is_qsfp = false;
324 : :
325 : 0 : ret = sxe2_drv_sfp_eeprom_read(adapter, &sfp_info);
326 [ # # ]: 0 : if (ret)
327 : 0 : goto l_end;
328 : :
329 : 0 : ret = 0;
330 : 0 : PMD_LOG_INFO(DRV, "Get sfp type success, type=%u", *type);
331 : :
332 : 0 : l_end:
333 : 0 : return ret;
334 : : }
335 : :
336 : 0 : static int32_t sxe2_sfp_module_info_get(struct sxe2_adapter *adapter,
337 : : struct rte_eth_dev_module_info *info)
338 : : {
339 : 0 : int32_t ret = -1;
340 : 0 : bool page_swap = false;
341 : 0 : uint8_t sff8472_rev = 0;
342 : 0 : uint8_t addr_mode = 0;
343 : 0 : struct sxe2_sfp_read_info sfp_info;
344 : :
345 : 0 : memset(&sfp_info, 0, sizeof(sfp_info));
346 : 0 : sfp_info.bus_addr = SXE2_SFP_E2P_I2C_7BIT_ADDR0;
347 : 0 : sfp_info.is_qsfp = false;
348 : 0 : sfp_info.len = 1;
349 : 0 : sfp_info.data = &sff8472_rev;
350 : 0 : sfp_info.offset = SXE2_MODULE_SFF_8472_COMP;
351 : 0 : sfp_info.page_cnt = 0;
352 : :
353 : 0 : ret = sxe2_drv_sfp_eeprom_read(adapter, &sfp_info);
354 [ # # ]: 0 : if (ret) {
355 : 0 : ret = -EIO;
356 : 0 : PMD_LOG_ERR(DRV, "Failed to read 8472 protocol, ret=%d", ret);
357 : 0 : goto l_end;
358 : : }
359 : :
360 : 0 : sfp_info.data = &addr_mode;
361 : 0 : sfp_info.offset = SXE2_MODULE_SFF_8472_SWAP;
362 : :
363 : 0 : ret = sxe2_drv_sfp_eeprom_read(adapter, &sfp_info);
364 [ # # ]: 0 : if (ret) {
365 : 0 : ret = -EIO;
366 : 0 : PMD_LOG_ERR(DRV, "Failed to read A2 page, ret=%d", ret);
367 : 0 : goto l_end;
368 : : }
369 : :
370 [ # # ]: 0 : if (addr_mode & SXE2_MODULE_SFF_ADDR_MODE) {
371 : 0 : PMD_LOG_ERR(DRV, "address change required to access page 0xA2, "
372 : : "but not supported. please report the module "
373 : : "type to the driver maintainers.");
374 : 0 : page_swap = true;
375 : : }
376 : :
377 : 0 : PMD_LOG_INFO(DRV, "Read sfp module info, sff_8472=%u, a2_page=%u, swap_page=%d",
378 : : sff8472_rev, addr_mode, page_swap);
379 : :
380 [ # # # # ]: 0 : if (sff8472_rev == SXE2_MODULE_SFF_8472_UNSUP ||
381 : 0 : page_swap ||
382 [ # # ]: 0 : !(addr_mode & SXE2_MODULE_SFF_DDM_IMPLEMENTED)) {
383 : 0 : info->type = SXE2_MODULE_SFF_8079;
384 : 0 : info->eeprom_len = SXE2_MODULE_SFF_8079_LEN;
385 : : } else {
386 : 0 : info->type = SXE2_MODULE_SFF_8472;
387 : 0 : info->eeprom_len = SXE2_MODULE_SFF_8472_LEN;
388 : : }
389 : :
390 : : ret = 0;
391 : :
392 : 0 : l_end:
393 : 0 : return ret;
394 : : }
395 : :
396 : : static int32_t
397 : 0 : sxe2_qsfp_module_info_get(struct sxe2_adapter *adapter, struct rte_eth_dev_module_info *info)
398 : : {
399 : 0 : int32_t ret = -1;
400 : 0 : uint8_t sff8636_rev = 0;
401 : 0 : struct sxe2_sfp_read_info sfp_info;
402 : :
403 : 0 : memset(&sfp_info, 0, sizeof(sfp_info));
404 : 0 : sfp_info.bus_addr = SXE2_SFP_E2P_I2C_7BIT_ADDR0;
405 : 0 : sfp_info.is_qsfp = true;
406 : 0 : sfp_info.len = 1;
407 : 0 : sfp_info.data = &sff8636_rev;
408 : 0 : sfp_info.offset = SXE2_MODULE_REVISION_ADDR;
409 : 0 : sfp_info.page_cnt = 0;
410 : :
411 : 0 : ret = sxe2_drv_sfp_eeprom_read(adapter, &sfp_info);
412 [ # # ]: 0 : if (ret) {
413 : 0 : ret = -EIO;
414 : 0 : PMD_LOG_ERR(DRV, "Failed to read 8636 protocol, ret=%d", ret);
415 : 0 : goto l_end;
416 : : }
417 : :
418 [ # # ]: 0 : if (sff8636_rev > 0x02) {
419 : 0 : info->type = SXE2_MODULE_SFF_8636;
420 : 0 : info->eeprom_len = SXE2_MODULE_SFF_8636_MAX_LEN;
421 : : } else {
422 : 0 : info->type = SXE2_MODULE_SFF_8436;
423 : 0 : info->eeprom_len = SXE2_MODULE_SFF_8436_MAX_LEN;
424 : : }
425 : :
426 : 0 : l_end:
427 : 0 : return ret;
428 : : }
429 : :
430 : : static int32_t
431 : 0 : sxe2_get_module_info(struct rte_eth_dev *dev, struct rte_eth_dev_module_info *info)
432 : : {
433 : 0 : int32_t ret = -1;
434 : 0 : uint8_t type = 0;
435 : 0 : struct sxe2_adapter *adapter = dev->data->dev_private;
436 : :
437 : 0 : ret = sxe2_sfp_type_get(adapter, &type);
438 [ # # ]: 0 : if (ret) {
439 : 0 : ret = -EIO;
440 : 0 : PMD_LOG_ERR(DRV, "Failed to read sfp type, ret=%d", ret);
441 : 0 : goto l_end;
442 : : }
443 : :
444 [ # # # ]: 0 : switch (type) {
445 : 0 : case SXE2_MODULE_SFF_SFP_TYPE:
446 : 0 : ret = sxe2_sfp_module_info_get(adapter, info);
447 [ # # ]: 0 : if (ret)
448 : 0 : goto l_end;
449 : : break;
450 : 0 : case SXE2_MODULE_TYPE_QSFP_PLUS:
451 : : case SXE2_MODULE_TYPE_QSFP28:
452 : 0 : ret = sxe2_qsfp_module_info_get(adapter, info);
453 [ # # ]: 0 : if (ret)
454 : 0 : goto l_end;
455 : : break;
456 : 0 : default:
457 : 0 : ret = -ENXIO;
458 : 0 : PMD_LOG_ERR(DRV, "Invalid sfp type, type=%d.", type);
459 : 0 : goto l_end;
460 : : }
461 : :
462 : 0 : PMD_LOG_INFO(DRV, "sfp eeprom type=%x, eeprom len=%d.", info->type, info->eeprom_len);
463 : :
464 : 0 : l_end:
465 : 0 : return ret;
466 : : }
467 : :
468 : : static int32_t
469 : 0 : sxe2_get_sfp_eeprom(struct sxe2_adapter *adapter, struct sxe2_sfp_read_info *sfp_info)
470 : : {
471 : 0 : int32_t ret = -1;
472 : 0 : uint16_t ori_len = sfp_info->len;
473 : 0 : uint16_t ori_offset = sfp_info->offset;
474 : :
475 [ # # ]: 0 : if ((ori_len + ori_offset) > SXE2_SFP_EEP_LEN_MAX) {
476 : 0 : sfp_info->len = (uint16_t)(SXE2_SFP_EEP_LEN_MAX - ori_offset);
477 : 0 : ret = sxe2_drv_sfp_eeprom_read(adapter, sfp_info);
478 [ # # ]: 0 : if (ret)
479 : 0 : goto l_end;
480 : 0 : sfp_info->bus_addr = SXE2_SFP_E2P_I2C_7BIT_ADDR1;
481 : 0 : sfp_info->len = (uint16_t)(ori_len - (SXE2_SFP_EEP_LEN_MAX - ori_offset));
482 : 0 : sfp_info->data = (uint8_t *)(sfp_info->data) + (SXE2_SFP_EEP_LEN_MAX - ori_offset);
483 : 0 : sfp_info->offset = 0;
484 : 0 : sfp_info->page_cnt = 0;
485 : 0 : ret = sxe2_drv_sfp_eeprom_read(adapter, sfp_info);
486 : : } else {
487 : 0 : ret = sxe2_drv_sfp_eeprom_read(adapter, sfp_info);
488 : : }
489 : :
490 : 0 : l_end:
491 [ # # ]: 0 : if (ret)
492 : 0 : PMD_LOG_ERR(DRV, "Failed to read sfp.");
493 : 0 : return ret;
494 : : }
495 : :
496 : : static int32_t
497 : 0 : sxe2_get_qsfp_eeprom(struct sxe2_adapter *adapter,
498 : : struct sxe2_sfp_read_info *sfp_info)
499 : : {
500 : 0 : int32_t ret = -1;
501 : 0 : uint16_t ori_len = sfp_info->len;
502 : 0 : uint16_t ori_offset = sfp_info->offset;
503 : 0 : uint16_t read_len = 0;
504 : 0 : uint16_t remain_len = 0;
505 : :
506 [ # # ]: 0 : if ((ori_len + ori_offset) > SXE2_SFP_EEP_LEN_MAX) {
507 : 0 : sfp_info->len = (uint16_t)(SXE2_SFP_EEP_LEN_MAX - ori_offset);
508 : 0 : ret = sxe2_drv_sfp_eeprom_read(adapter, sfp_info);
509 [ # # ]: 0 : if (ret)
510 : 0 : goto l_end;
511 : :
512 : 0 : do {
513 : 0 : read_len = read_len + sfp_info->len;
514 : 0 : sfp_info->data = (uint8_t *)(sfp_info->data) + sfp_info->len;
515 : 0 : sfp_info->offset = SXE2_QSFP_PAGE_OFST_START;
516 : 0 : sfp_info->page_cnt++;
517 : 0 : remain_len = (uint16_t)(ori_len - read_len);
518 : 0 : sfp_info->len = (remain_len > SXE2_QSFP_PAGE_OFST_START) ?
519 : 0 : SXE2_QSFP_PAGE_OFST_START : remain_len;
520 : 0 : ret = sxe2_drv_sfp_eeprom_read(adapter, sfp_info);
521 [ # # ]: 0 : if (ret)
522 : 0 : goto l_end;
523 [ # # ]: 0 : } while (remain_len > SXE2_QSFP_PAGE_OFST_START);
524 : : } else {
525 : 0 : ret = sxe2_drv_sfp_eeprom_read(adapter, sfp_info);
526 : : }
527 : :
528 : 0 : l_end:
529 [ # # ]: 0 : if (ret)
530 : 0 : PMD_LOG_ERR(DRV, "Failed to read sfp.");
531 : 0 : return ret;
532 : : }
533 : :
534 : : static int32_t
535 : 0 : sxe2_get_module_eeprom(struct rte_eth_dev *dev, struct rte_dev_eeprom_info *info)
536 : : {
537 : 0 : int32_t ret = -1;
538 : 0 : uint8_t type = 0;
539 : 0 : struct sxe2_adapter *adapter = dev->data->dev_private;
540 : 0 : struct sxe2_sfp_read_info sfp_info;
541 : :
542 [ # # ]: 0 : memset(&sfp_info, 0, sizeof(sfp_info));
543 : :
544 [ # # # # : 0 : if (!info || !info->length || !info->data ||
# # ]
545 [ # # ]: 0 : info->offset >= SXE2_SFP_EEP_LEN_MAX) {
546 : 0 : ret = -EINVAL;
547 : 0 : goto l_end;
548 : : }
549 : :
550 : 0 : PMD_LOG_INFO(DRV, "Dump sfp eeprom info offset=0x%x, len=0x%x.",
551 : : info->offset, info->length);
552 : :
553 : 0 : ret = sxe2_sfp_type_get(adapter, &type);
554 [ # # ]: 0 : if (ret) {
555 : 0 : ret = -EIO;
556 : 0 : PMD_LOG_ERR(DRV, "Failed to read sfp type, ret=%d", ret);
557 : 0 : goto l_end;
558 : : }
559 : :
560 : 0 : sfp_info.bus_addr = SXE2_SFP_E2P_I2C_7BIT_ADDR0;
561 : 0 : sfp_info.len = info->length;
562 : 0 : sfp_info.data = info->data;
563 : 0 : sfp_info.offset = info->offset;
564 : 0 : sfp_info.page_cnt = 0;
565 : :
566 [ # # # ]: 0 : switch (type) {
567 : 0 : case SXE2_MODULE_SFF_SFP_TYPE:
568 [ # # ]: 0 : if (info->length > SXE2_SFP_EEP_LEN_MAX * 2) {
569 : 0 : ret = -EINVAL;
570 : 0 : PMD_LOG_ERR(DRV, "sfp read size[%u] > eeprom max size[%d], ret=%d",
571 : : info->length, SXE2_SFP_EEP_LEN_MAX * 2, ret);
572 : 0 : goto l_end;
573 : : }
574 : 0 : sfp_info.is_qsfp = false;
575 : 0 : ret = sxe2_get_sfp_eeprom(adapter, &sfp_info);
576 [ # # ]: 0 : if (ret)
577 : 0 : goto l_end;
578 : : break;
579 : 0 : case SXE2_MODULE_TYPE_QSFP_PLUS:
580 : : case SXE2_MODULE_TYPE_QSFP28:
581 [ # # ]: 0 : if (info->length > SXE2_MODULE_SFF_8636_MAX_LEN) {
582 : 0 : ret = -EINVAL;
583 : 0 : PMD_LOG_ERR(DRV, "sfp read size[%u] > eeprom max size[%d], ret=%d",
584 : : info->length, SXE2_SFP_EEP_LEN_MAX * 2, ret);
585 : 0 : goto l_end;
586 : : }
587 : 0 : sfp_info.is_qsfp = true;
588 : 0 : ret = sxe2_get_qsfp_eeprom(adapter, &sfp_info);
589 [ # # ]: 0 : if (ret)
590 : 0 : goto l_end;
591 : : break;
592 : 0 : default:
593 : 0 : ret = -ENXIO;
594 : 0 : PMD_LOG_ERR(DRV, "Invalid sfp type, type=%d.", type);
595 : 0 : goto l_end;
596 : : }
597 : :
598 : 0 : l_end:
599 : 0 : return ret;
600 : : }
601 : :
602 : : static enum sxe2_udp_tunnel_protocol
603 : 0 : sxe2_udp_tunnel_type_rte_to_sxe2(enum rte_eth_tunnel_type rte_type)
604 : : {
605 : 0 : static enum sxe2_udp_tunnel_protocol sxe2_udp_proto_map[RTE_ETH_TUNNEL_TYPE_MAX] = {
606 : : [RTE_ETH_TUNNEL_TYPE_NONE] = SXE2_UDP_TUNNEL_MAX,
607 : : [RTE_ETH_TUNNEL_TYPE_VXLAN] = SXE2_UDP_TUNNEL_PROTOCOL_VXLAN,
608 : : [RTE_ETH_TUNNEL_TYPE_GENEVE] = SXE2_UDP_TUNNEL_PROTOCOL_GENEVE,
609 : : [RTE_ETH_TUNNEL_TYPE_TEREDO] = SXE2_UDP_TUNNEL_PROTOCOL_TEREDO,
610 : : [RTE_ETH_TUNNEL_TYPE_NVGRE] = SXE2_UDP_TUNNEL_PROTOCOL_NVGRE,
611 : : [RTE_ETH_TUNNEL_TYPE_IP_IN_GRE] = SXE2_UDP_TUNNEL_MAX,
612 : : [RTE_ETH_L2_TUNNEL_TYPE_E_TAG] = SXE2_UDP_TUNNEL_MAX,
613 : : [RTE_ETH_TUNNEL_TYPE_VXLAN_GPE] = SXE2_UDP_TUNNEL_PROTOCOL_VXLAN_GPE,
614 : : [RTE_ETH_TUNNEL_TYPE_ECPRI] = SXE2_UDP_TUNNEL_PROTOCOL_ECPRI
615 : : };
616 : :
617 [ # # ]: 0 : if (rte_type >= RTE_ETH_TUNNEL_TYPE_MAX) {
618 : 0 : PMD_LOG_ERR(DRV, "Invalid rte_eth_tunnel_type %d!", rte_type);
619 : 0 : rte_type = RTE_ETH_TUNNEL_TYPE_NONE;
620 : : }
621 : :
622 : 0 : return sxe2_udp_proto_map[rte_type];
623 : : }
624 : :
625 : 0 : int32_t sxe2_udp_tunnel_port_add_common(struct sxe2_adapter *ad,
626 : : enum sxe2_udp_tunnel_protocol tunnel_proto,
627 : : uint16_t udp_port)
628 : : {
629 : 0 : struct sxe2_udp_tunnel_cfg *tunnel_config;
630 : 0 : int32_t ret = -1;
631 : :
632 : 0 : rte_spinlock_lock(&ad->udp_tunnel_ctx.lock);
633 : :
634 : 0 : tunnel_config = &ad->udp_tunnel_ctx.tunnel_conf[tunnel_proto];
635 : :
636 [ # # ]: 0 : if (tunnel_config->dev_status == SXE2_UDP_TUNNEL_ENABLE) {
637 [ # # ]: 0 : if (udp_port == tunnel_config->dev_port &&
638 [ # # ]: 0 : tunnel_config->dev_ref_cnt < 0xFFFFU) {
639 : 0 : tunnel_config->dev_ref_cnt++;
640 : 0 : ret = 0;
641 : 0 : goto l_unlock_end;
642 : : } else {
643 : 0 : PMD_LOG_ERR(DRV, "Adding multiple ports to the same protocol "
644 : : "is not supported!");
645 : 0 : ret = -EINVAL;
646 : 0 : goto l_unlock_end;
647 : : }
648 : : } else {
649 : 0 : ret = sxe2_drv_udp_tunnel_add(ad, tunnel_proto, udp_port);
650 [ # # ]: 0 : if (ret != 0)
651 : 0 : goto l_unlock_end;
652 : :
653 : 0 : tunnel_config->protocol = tunnel_proto;
654 : 0 : tunnel_config->dev_port = udp_port;
655 : 0 : tunnel_config->dev_status = SXE2_UDP_TUNNEL_ENABLE;
656 : 0 : tunnel_config->dev_ref_cnt++;
657 : : }
658 : :
659 : 0 : l_unlock_end:
660 : 0 : rte_spinlock_unlock(&ad->udp_tunnel_ctx.lock);
661 : 0 : return ret;
662 : : }
663 : :
664 : 0 : int32_t sxe2_udp_tunnel_port_del_common(struct sxe2_adapter *ad,
665 : : enum sxe2_udp_tunnel_protocol tunnel_proto,
666 : : uint16_t udp_port)
667 : : {
668 : 0 : struct sxe2_udp_tunnel_cfg *tunnel_config;
669 : 0 : int32_t ret = -1;
670 : :
671 : 0 : rte_spinlock_lock(&ad->udp_tunnel_ctx.lock);
672 : 0 : tunnel_config = &ad->udp_tunnel_ctx.tunnel_conf[tunnel_proto];
673 : :
674 [ # # ]: 0 : if (tunnel_config->dev_status == SXE2_UDP_TUNNEL_ENABLE &&
675 [ # # ]: 0 : udp_port == tunnel_config->dev_port) {
676 [ # # ]: 0 : if (tunnel_config->dev_ref_cnt > 1) {
677 : 0 : tunnel_config->dev_ref_cnt--;
678 : 0 : ret = 0;
679 : 0 : goto l_unlock_end;
680 : : } else {
681 : 0 : ret = sxe2_drv_udp_tunnel_del(ad, tunnel_proto, udp_port);
682 [ # # ]: 0 : if (ret != 0)
683 : 0 : goto l_unlock_end;
684 : :
685 : 0 : tunnel_config->dev_status = SXE2_UDP_TUNNEL_DISABLE;
686 : 0 : tunnel_config->dev_ref_cnt = 0;
687 : : }
688 : 0 : goto l_unlock_end;
689 : : }
690 : :
691 : : ret = -EINVAL;
692 : :
693 : 0 : l_unlock_end:
694 : 0 : rte_spinlock_unlock(&ad->udp_tunnel_ctx.lock);
695 : 0 : return ret;
696 : : }
697 : :
698 : 0 : static int32_t sxe2_udp_tunnel_port_clear(struct rte_eth_dev *dev)
699 : : {
700 : 0 : struct sxe2_adapter *ad = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
701 : 0 : struct sxe2_udp_tunnel_cfg *tunnel_config;
702 : 0 : int32_t ret = 0;
703 : 0 : uint16_t tunnel_proto = 0;
704 : :
705 : 0 : rte_spinlock_lock(&ad->udp_tunnel_ctx.lock);
706 : :
707 [ # # ]: 0 : for (tunnel_proto = 0; tunnel_proto < SXE2_UDP_TUNNEL_MAX; tunnel_proto++) {
708 : 0 : tunnel_config = &ad->udp_tunnel_ctx.tunnel_conf[tunnel_proto];
709 [ # # ]: 0 : if (tunnel_config->dev_status == SXE2_UDP_TUNNEL_ENABLE) {
710 : 0 : ret = sxe2_drv_udp_tunnel_del(ad, tunnel_config->protocol,
711 : 0 : tunnel_config->dev_port);
712 [ # # ]: 0 : if (ret) {
713 : 0 : PMD_LOG_ERR(DRV, "Failed to delete udp tunnel port %d, proto %d",
714 : : tunnel_config->dev_port, tunnel_config->protocol);
715 : 0 : goto l_unlock_end;
716 : : }
717 : :
718 : 0 : tunnel_config->dev_status = SXE2_UDP_TUNNEL_DISABLE;
719 : 0 : tunnel_config->dev_ref_cnt = 0;
720 : : }
721 : : }
722 : 0 : l_unlock_end:
723 : 0 : rte_spinlock_unlock(&ad->udp_tunnel_ctx.lock);
724 : 0 : return ret;
725 : : }
726 : :
727 : 0 : static int32_t sxe2_udp_tunnel_port_add(struct rte_eth_dev *dev,
728 : : struct rte_eth_udp_tunnel *tunnel_udp)
729 : : {
730 : 0 : int32_t ret = 0;
731 : 0 : enum sxe2_udp_tunnel_protocol tunnel_proto;
732 : 0 : struct sxe2_adapter *ad = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
733 : :
734 [ # # ]: 0 : if (tunnel_udp->udp_port == 0) {
735 : 0 : ret = -EINVAL;
736 : 0 : goto l_end;
737 : : }
738 : :
739 : 0 : tunnel_proto = sxe2_udp_tunnel_type_rte_to_sxe2(tunnel_udp->prot_type);
740 [ # # ]: 0 : if (tunnel_proto >= SXE2_UDP_TUNNEL_MAX) {
741 : 0 : ret = -EINVAL;
742 : 0 : goto l_end;
743 : : }
744 : :
745 : 0 : ret = sxe2_udp_tunnel_port_add_common(ad, tunnel_proto, tunnel_udp->udp_port);
746 [ # # ]: 0 : if (ret) {
747 : 0 : PMD_LOG_ERR(DRV, "Add tunnel port failed, ret = %d", ret);
748 : 0 : goto l_end;
749 : : }
750 : :
751 : 0 : l_end:
752 : 0 : return ret;
753 : : }
754 : :
755 : 0 : static int32_t sxe2_udp_tunnel_port_del(struct rte_eth_dev *dev,
756 : : struct rte_eth_udp_tunnel *tunnel_udp)
757 : : {
758 : 0 : int32_t ret = 0;
759 : 0 : enum sxe2_udp_tunnel_protocol tunnel_proto;
760 : 0 : struct sxe2_adapter *ad = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
761 : :
762 : 0 : tunnel_proto = sxe2_udp_tunnel_type_rte_to_sxe2(tunnel_udp->prot_type);
763 [ # # ]: 0 : if (tunnel_proto >= SXE2_UDP_TUNNEL_MAX) {
764 : 0 : ret = -EINVAL;
765 : 0 : goto l_end;
766 : : }
767 : :
768 : 0 : ret = sxe2_udp_tunnel_port_del_common(ad, tunnel_proto, tunnel_udp->udp_port);
769 [ # # ]: 0 : if (ret) {
770 : 0 : PMD_LOG_ERR(DRV, "Delete tunnel port failed, ret = %d", ret);
771 : 0 : goto l_end;
772 : : }
773 : :
774 : 0 : l_end:
775 : 0 : return ret;
776 : : }
777 : :
778 : 0 : static int32_t sxe2_dev_infos_get(struct rte_eth_dev *dev,
779 : : struct rte_eth_dev_info *dev_info)
780 : : {
781 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
782 : 0 : struct sxe2_vsi *vsi = adapter->vsi_ctxt.main_vsi;
783 : :
784 : 0 : dev_info->max_rx_queues = vsi->rxqs.q_cnt;
785 : 0 : dev_info->max_tx_queues = vsi->txqs.q_cnt;
786 : 0 : dev_info->min_rx_bufsize = SXE2_MIN_BUF_SIZE;
787 : 0 : dev_info->max_rx_pktlen = SXE2_FRAME_SIZE_MAX;
788 : 0 : dev_info->max_lro_pkt_size = SXE2_FRAME_SIZE_MAX * SXE2_RX_LRO_DESC_MAX_NUM;
789 : 0 : dev_info->max_mtu = dev_info->max_rx_pktlen - SXE2_ETH_OVERHEAD;
790 : 0 : dev_info->min_mtu = RTE_ETHER_MIN_MTU;
791 : :
792 : 0 : dev_info->rx_offload_capa =
793 : : RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
794 : : RTE_ETH_RX_OFFLOAD_KEEP_CRC |
795 : : RTE_ETH_RX_OFFLOAD_SCATTER |
796 : : RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
797 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
798 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
799 : : RTE_ETH_RX_OFFLOAD_SCTP_CKSUM |
800 : : RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
801 : : RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT |
802 : : #ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
803 : : RTE_ETH_RX_OFFLOAD_QINQ_STRIP |
804 : : #endif
805 : : RTE_ETH_RX_OFFLOAD_VLAN_EXTEND |
806 : : RTE_ETH_RX_OFFLOAD_TCP_LRO;
807 : :
808 : 0 : dev_info->tx_offload_capa =
809 : : RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
810 : : RTE_ETH_TX_OFFLOAD_QINQ_INSERT |
811 : : RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
812 : : RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE |
813 : : RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
814 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
815 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
816 : : RTE_ETH_TX_OFFLOAD_SCTP_CKSUM |
817 : : RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM |
818 : : RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM |
819 : : RTE_ETH_TX_OFFLOAD_TCP_TSO |
820 : : RTE_ETH_TX_OFFLOAD_UDP_TSO |
821 : : RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO |
822 : : RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO |
823 : : RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO |
824 : : RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO;
825 : :
826 : 0 : dev_info->rx_queue_offload_capa =
827 : : RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT |
828 : : RTE_ETH_RX_OFFLOAD_KEEP_CRC |
829 : : RTE_ETH_RX_OFFLOAD_SCATTER |
830 : : RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
831 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
832 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
833 : : RTE_ETH_RX_OFFLOAD_SCTP_CKSUM |
834 : : RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
835 : : RTE_ETH_RX_OFFLOAD_TCP_LRO;
836 : 0 : dev_info->tx_queue_offload_capa =
837 : : RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE |
838 : : RTE_ETH_TX_OFFLOAD_TCP_TSO |
839 : : RTE_ETH_TX_OFFLOAD_UDP_TSO |
840 : : RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
841 : : RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
842 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
843 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
844 : : RTE_ETH_TX_OFFLOAD_SCTP_CKSUM |
845 : : RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM |
846 : : RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM |
847 : : RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO |
848 : : RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO |
849 : : RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO |
850 : : RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO;
851 : :
852 : :
853 [ # # ]: 0 : if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_PTP)
854 : 0 : dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
855 : :
856 [ # # ]: 0 : if (sxe2_ipsec_supported(adapter)) {
857 : 0 : dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_SECURITY;
858 : 0 : dev_info->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_SECURITY;
859 : : }
860 : :
861 [ # # ]: 0 : if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_RSS) {
862 : 0 : dev_info->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
863 : 0 : dev_info->flow_type_rss_offloads |= SXE2_RSS_HF_SUPPORT_ALL;
864 : 0 : dev_info->reta_size = adapter->rss_ctxt.rss_lut_size;
865 : 0 : dev_info->hash_key_size = adapter->rss_ctxt.rss_key_size;
866 : 0 : dev_info->rss_algo_capa =
867 : : RTE_ETH_HASH_ALGO_TO_CAPA(RTE_ETH_HASH_FUNCTION_DEFAULT) |
868 : : RTE_ETH_HASH_ALGO_TO_CAPA(RTE_ETH_HASH_FUNCTION_TOEPLITZ) |
869 : : RTE_ETH_HASH_ALGO_TO_CAPA(RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) |
870 : : RTE_ETH_HASH_ALGO_TO_CAPA(RTE_ETH_HASH_FUNCTION_SIMPLE_XOR);
871 : : }
872 : :
873 : 0 : dev_info->default_rxconf = (struct rte_eth_rxconf) {
874 : : .rx_thresh = {
875 : : .pthresh = SXE2_DEFAULT_RX_PTHRESH,
876 : : .hthresh = SXE2_DEFAULT_RX_HTHRESH,
877 : : .wthresh = SXE2_DEFAULT_RX_WTHRESH,
878 : : },
879 : : .rx_free_thresh = SXE2_DEFAULT_RX_FREE_THRESH,
880 : : .rx_drop_en = 0,
881 : : .offloads = 0,
882 : : };
883 : :
884 : 0 : dev_info->default_txconf = (struct rte_eth_txconf) {
885 : : .tx_thresh = {
886 : : .pthresh = SXE2_DEFAULT_TX_PTHRESH,
887 : : .hthresh = SXE2_DEFAULT_TX_HTHRESH,
888 : : .wthresh = SXE2_DEFAULT_TX_WTHRESH,
889 : : },
890 : : .tx_free_thresh = SXE2_DEFAULT_TX_FREE_THRESH,
891 : : .tx_rs_thresh = SXE2_DEFAULT_TX_RSBIT_THRESH,
892 : : .offloads = 0,
893 : : };
894 : :
895 : 0 : dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
896 : : .nb_max = SXE2_MAX_RING_DESC,
897 : : .nb_min = SXE2_MIN_RING_DESC,
898 : : .nb_align = SXE2_ALIGN,
899 : : };
900 : :
901 : 0 : dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
902 : : .nb_max = SXE2_MAX_RING_DESC,
903 : : .nb_min = SXE2_MIN_RING_DESC,
904 : : .nb_align = SXE2_ALIGN,
905 : : .nb_mtu_seg_max = SXE2_TX_MTU_SEG_MAX,
906 : : .nb_seg_max = SXE2_MAX_RING_DESC,
907 : : };
908 : :
909 : 0 : dev_info->speed_capa = RTE_ETH_LINK_SPEED_10G | RTE_ETH_LINK_SPEED_25G |
910 : : RTE_ETH_LINK_SPEED_50G | RTE_ETH_LINK_SPEED_100G;
911 : :
912 : 0 : dev_info->default_rxportconf.burst_size = SXE2_RX_MAX_BURST;
913 : 0 : dev_info->default_txportconf.burst_size = SXE2_TX_MAX_BURST;
914 : 0 : dev_info->default_rxportconf.nb_queues = 1;
915 : 0 : dev_info->default_txportconf.nb_queues = 1;
916 : 0 : dev_info->default_rxportconf.ring_size = SXE2_RING_SIZE_MIN;
917 : 0 : dev_info->default_txportconf.ring_size = SXE2_RING_SIZE_MIN;
918 : :
919 : 0 : dev_info->rx_seg_capa.max_nseg = SXE2_RX_MAX_NSEG;
920 : :
921 : 0 : dev_info->rx_seg_capa.multi_pools = true;
922 : :
923 : 0 : dev_info->rx_seg_capa.offset_allowed = false;
924 : :
925 : 0 : dev_info->rx_seg_capa.offset_align_log2 = false;
926 : :
927 : 0 : return 0;
928 : : }
929 : :
930 : : static const uint32_t *
931 : 0 : sxe2_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused,
932 : : size_t *no_of_elements __rte_unused)
933 : : {
934 : 0 : static const uint32_t ptypes[] = {
935 : : RTE_PTYPE_L2_ETHER,
936 : : RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
937 : : RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_UDP,
938 : : RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_TCP,
939 : : RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_SCTP,
940 : : RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
941 : : RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_UDP,
942 : : RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_TCP,
943 : : RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_SCTP,
944 : :
945 : : RTE_PTYPE_TUNNEL_GRENAT,
946 : :
947 : : RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER,
948 : :
949 : : RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
950 : : RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
951 : : RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
952 : : RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
953 : :
954 : : RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
955 : : RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_UDP,
956 : : RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
957 : : RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_TCP,
958 : : RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
959 : : RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_SCTP,
960 : :
961 : : RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
962 : : RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_UDP,
963 : : RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
964 : : RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_TCP,
965 : : RTE_PTYPE_TUNNEL_GRENAT | RTE_PTYPE_INNER_L2_ETHER |
966 : : RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_INNER_L4_SCTP,
967 : :
968 : : RTE_PTYPE_UNKNOWN
969 : : };
970 : :
971 : 0 : return ptypes;
972 : : }
973 : :
974 : 0 : static int32_t sxe2_parse_fnav_stat_type(const char *key, const char *value, void *args)
975 : : {
976 : 0 : int32_t ret = -EINVAL;
977 : 0 : uint8_t *num = (uint8_t *)args;
978 : 0 : unsigned long fnav_stat_type;
979 : 0 : char *endptr = NULL;
980 : :
981 [ # # ]: 0 : if (value == NULL || args == NULL) {
982 : 0 : ret = 0;
983 : 0 : goto l_end;
984 : : }
985 : 0 : errno = 0;
986 : 0 : fnav_stat_type = strtoul(value, &endptr, 10);
987 [ # # # # : 0 : if (errno != 0 || endptr == value || *endptr != '\0') {
# # ]
988 : 0 : PMD_LOG_WARN(INIT, "%s: \"%s\" is not a valid int value.",
989 : : key, value);
990 : 0 : goto l_end;
991 : : }
992 [ # # ]: 0 : if (fnav_stat_type > SXE2_FNAV_STAT_ENA_ALL ||
993 : : fnav_stat_type == SXE2_FNAV_STAT_ENA_NONE) {
994 : 0 : PMD_LOG_ERR(INIT, "%s: \"%s\" out of range [1-3].",
995 : : key, value);
996 : 0 : goto l_end;
997 : : }
998 : 0 : *num = (uint8_t)fnav_stat_type;
999 : 0 : ret = 0;
1000 : 0 : l_end:
1001 : 0 : return ret;
1002 : : }
1003 : :
1004 : 0 : static int32_t sxe2_parse_sched_layer_mode(const char *key, const char *value, void *args)
1005 : : {
1006 : 0 : int32_t ret = -EINVAL;
1007 : 0 : uint8_t *num = (uint8_t *)args;
1008 : 0 : unsigned long sched_layer_mode;
1009 : 0 : char *endptr = NULL;
1010 : :
1011 [ # # ]: 0 : if (value == NULL || args == NULL) {
1012 : 0 : ret = 0;
1013 : 0 : goto l_end;
1014 : : }
1015 : 0 : errno = 0;
1016 : 0 : sched_layer_mode = strtoul(value, &endptr, 10);
1017 [ # # # # : 0 : if (errno != 0 || endptr == value || *endptr != '\0') {
# # ]
1018 : 0 : PMD_LOG_WARN(INIT, "%s: \"%s\" is not a valid int value.",
1019 : : key, value);
1020 : 0 : goto l_end;
1021 : : }
1022 [ # # ]: 0 : if (sched_layer_mode > SXE2_TXSCH_NODE_ADJ_LVL_MAX) {
1023 : 0 : PMD_LOG_ERR(INIT, "%s: \"%s\" > 3.",
1024 : : key, value);
1025 : 0 : goto l_end;
1026 : : }
1027 : 0 : *num = (uint8_t)sched_layer_mode;
1028 : 0 : ret = 0;
1029 : 0 : l_end:
1030 : 0 : return ret;
1031 : : }
1032 : :
1033 : 0 : static int32_t sxe2_parse_flow_dup_pattern_mode(const char *key, const char *value, void *args)
1034 : : {
1035 : 0 : uint8_t *num = (uint8_t *)args;
1036 : 0 : char *end;
1037 : 0 : unsigned long val;
1038 : 0 : int32_t ret = -EINVAL;
1039 : :
1040 [ # # ]: 0 : if (value == NULL || args == NULL) {
1041 : 0 : ret = 0;
1042 : 0 : goto l_end;
1043 : : }
1044 : 0 : errno = 0;
1045 : 0 : val = strtoul(value, &end, 10);
1046 [ # # # # : 0 : if (errno != 0 || end == value || *end != '\0') {
# # ]
1047 : 0 : PMD_LOG_ERR(INIT, "Invalid 8-bit integer value for key %s: %s", key, value);
1048 : 0 : goto l_end;
1049 : : }
1050 : :
1051 [ # # ]: 0 : if (val >= SXE2_FLOW_SW_PATTERN_MAX) {
1052 : 0 : PMD_LOG_ERR(INIT, "%s: \"%s\" out of range [0-%u].",
1053 : : key, value, SXE2_FLOW_SW_PATTERN_MAX - 1);
1054 : 0 : goto l_end;
1055 : : }
1056 : :
1057 : : /* Convert user values to internal enum:
1058 : : * user 0 (reject) -> SXE2_FLOW_SW_PATTERN_ONLY (0)
1059 : : * user 1 (FIFO) -> SXE2_FLOW_SW_PATTERN_FIRST (2)
1060 : : * user 2 (LIFO) -> SXE2_FLOW_SW_PATTERN_LAST (1)
1061 : : */
1062 : 0 : static const uint8_t udc_tbl[] = {
1063 : : SXE2_FLOW_SW_PATTERN_ONLY,
1064 : : SXE2_FLOW_SW_PATTERN_FIRST,
1065 : : SXE2_FLOW_SW_PATTERN_LAST,
1066 : : };
1067 : 0 : *num = udc_tbl[val];
1068 : 0 : ret = 0;
1069 : 0 : l_end:
1070 : 0 : return ret;
1071 : : }
1072 : :
1073 : 0 : static int32_t sxe2_parse_bool(const char *key, const char *value, void *args)
1074 : : {
1075 : 0 : int32_t ret = -EINVAL;
1076 : 0 : uint8_t *num = (uint8_t *)args;
1077 : 0 : unsigned long bool_val;
1078 : 0 : char *endptr = NULL;
1079 : :
1080 [ # # ]: 0 : if (value == NULL || args == NULL) {
1081 : 0 : ret = 0;
1082 : 0 : goto l_end;
1083 : : }
1084 : 0 : errno = 0;
1085 : 0 : bool_val = strtoul(value, &endptr, 10);
1086 [ # # # # : 0 : if (errno != 0 || endptr == value || *endptr != '\0') {
# # ]
1087 : 0 : PMD_LOG_WARN(INIT, "%s: \"%s\" is not a valid int value.",
1088 : : key, value);
1089 : 0 : goto l_end;
1090 : : }
1091 [ # # ]: 0 : if (bool_val != 0 && bool_val != 1) {
1092 : 0 : PMD_LOG_ERR(INIT, "%s: \"%s\" out of range [0|1].",
1093 : : key, value);
1094 : 0 : goto l_end;
1095 : : }
1096 : 0 : *num = (uint8_t)bool_val;
1097 : 0 : ret = 0;
1098 : 0 : l_end:
1099 : 0 : return ret;
1100 : : }
1101 : :
1102 : 0 : struct sxe2_pci_map_bar_info *sxe2_dev_get_bar_info(struct sxe2_adapter *adapter,
1103 : : enum sxe2_pci_map_resource res_type)
1104 : : {
1105 : 0 : struct sxe2_pci_map_context *map_ctxt = &adapter->map_ctxt;
1106 : 0 : struct sxe2_pci_map_bar_info *bar_info = NULL;
1107 : 0 : uint8_t bar_idx = SXE2_PCI_MAP_BAR_INVALID;
1108 : 0 : uint8_t i;
1109 : :
1110 : 0 : bar_idx = map_ctxt->addr_info[res_type].bar_idx;
1111 [ # # ]: 0 : if (bar_idx == SXE2_PCI_MAP_BAR_INVALID) {
1112 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Invalid bar index with resource type %d", res_type);
1113 : 0 : goto l_end;
1114 : : }
1115 : :
1116 [ # # ]: 0 : for (i = 0; i < map_ctxt->bar_cnt; i++) {
1117 [ # # ]: 0 : if (bar_idx == map_ctxt->bar_info[i].bar_idx) {
1118 : : bar_info = &map_ctxt->bar_info[i];
1119 : : break;
1120 : : }
1121 : : }
1122 : :
1123 : 0 : l_end:
1124 : 0 : return bar_info;
1125 : : }
1126 : :
1127 : 0 : void *sxe2_pci_map_addr_get(struct sxe2_adapter *adapter,
1128 : : enum sxe2_pci_map_resource res_type,
1129 : : uint16_t idx_in_func)
1130 : : {
1131 : 0 : struct sxe2_pci_map_context *map_ctxt = &adapter->map_ctxt;
1132 : 0 : struct sxe2_pci_map_segment_info *seg_info = NULL;
1133 : 0 : struct sxe2_pci_map_bar_info *bar_info = NULL;
1134 : 0 : void *addr = NULL;
1135 : 0 : uintptr_t calc_addr = 0;
1136 : 0 : uint8_t reg_width = 0;
1137 : 0 : uint8_t i = 0;
1138 : :
1139 : 0 : bar_info = sxe2_dev_get_bar_info(adapter, res_type);
1140 [ # # ]: 0 : if (bar_info == NULL) {
1141 : 0 : PMD_DEV_LOG_WARN(adapter, INIT, "Failed to get bar info, res_type=[%d]",
1142 : : res_type);
1143 : 0 : goto l_end;
1144 : : }
1145 : 0 : seg_info = bar_info->seg_info;
1146 : :
1147 : 0 : reg_width = map_ctxt->addr_info[res_type].reg_width;
1148 [ # # ]: 0 : if (reg_width == 0) {
1149 : 0 : PMD_DEV_LOG_WARN(adapter, INIT, "Invalid reg width with resource type %d",
1150 : : res_type);
1151 : 0 : goto l_end;
1152 : : }
1153 : :
1154 [ # # ]: 0 : for (i = 0; i < bar_info->map_cnt; i++) {
1155 : 0 : seg_info = &bar_info->seg_info[i];
1156 [ # # ]: 0 : if (res_type == seg_info->type) {
1157 : 0 : calc_addr = (uintptr_t)seg_info->addr;
1158 : 0 : calc_addr += (uintptr_t)seg_info->page_inner_offset;
1159 : 0 : calc_addr += (uintptr_t)reg_width * (uintptr_t)idx_in_func;
1160 : 0 : addr = (void *)calc_addr;
1161 : 0 : goto l_end;
1162 : : }
1163 : : }
1164 : :
1165 : 0 : l_end:
1166 : 0 : return addr;
1167 : : }
1168 : :
1169 : 0 : static int32_t sxe2_args_parse(struct rte_eth_dev *dev, struct sxe2_dev_kvargs_info *kvargs)
1170 : : {
1171 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
1172 : 0 : int32_t ret = 0;
1173 : 0 : PMD_INIT_FUNC_TRACE();
1174 : :
1175 : 0 : adapter->devargs.flow_dup_pattern_mode = SXE2_FLOW_SW_PATTERN_FIRST;
1176 : :
1177 [ # # ]: 0 : if (kvargs == NULL)
1178 : 0 : goto l_end;
1179 : 0 : ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_FNAV_STAT_TYPE,
1180 : : &sxe2_parse_fnav_stat_type,
1181 : 0 : &adapter->devargs.fnav_stat_type);
1182 [ # # ]: 0 : if (ret) {
1183 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse fnav stat type, ret:%d", ret);
1184 : 0 : goto l_end;
1185 : : }
1186 : :
1187 : 0 : ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_NO_SCHED_MODE,
1188 : : &sxe2_parse_bool,
1189 : 0 : &adapter->devargs.no_sched_mode);
1190 [ # # ]: 0 : if (ret) {
1191 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse no sched mode, ret:%d", ret);
1192 : 0 : goto l_end;
1193 : : }
1194 : 0 : ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_SCHED_LAYER_MODE,
1195 : : &sxe2_parse_sched_layer_mode,
1196 : 0 : &adapter->devargs.sched_layer_mode);
1197 [ # # ]: 0 : if (ret) {
1198 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse sched layer mode, ret:%d", ret);
1199 : 0 : goto l_end;
1200 : : }
1201 : :
1202 : 0 : ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_FLOW_DUP_PATTERN_MODE,
1203 : : &sxe2_parse_flow_dup_pattern_mode,
1204 : 0 : &adapter->devargs.flow_dup_pattern_mode);
1205 [ # # ]: 0 : if (ret) {
1206 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse flow dup pattern mode, ret:%d",
1207 : : ret);
1208 : 0 : goto l_end;
1209 : : }
1210 : :
1211 : 0 : ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_FUNC_FLOW_DIRCT,
1212 : : &sxe2_parse_bool,
1213 : 0 : &adapter->devargs.func_flow_direct_en);
1214 [ # # ]: 0 : if (ret) {
1215 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse function flow rule enable,"
1216 : : "ret:%d", ret);
1217 : 0 : goto l_end;
1218 : : }
1219 : 0 : ret = sxe2_kvargs_process(kvargs, SXE2_DEVARG_RX_LOW_LATENCY,
1220 : : &sxe2_parse_bool,
1221 : 0 : &adapter->devargs.rx_low_latency);
1222 [ # # ]: 0 : if (ret) {
1223 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to parse rx low latency, ret:%d", ret);
1224 : 0 : goto l_end;
1225 : : }
1226 : 0 : l_end:
1227 : 0 : return ret;
1228 : : }
1229 : :
1230 : 0 : static int32_t sxe2_eth_init(struct rte_eth_dev *dev)
1231 : : {
1232 : 0 : int32_t ret = 0;
1233 : :
1234 : 0 : ret = sxe2_filter_init(dev);
1235 [ # # ]: 0 : if (ret) {
1236 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize l2 filter, ret:%d", ret);
1237 : 0 : goto l_end;
1238 : : }
1239 : :
1240 : 0 : ret = sxe2_link_update_init(dev);
1241 [ # # ]: 0 : if (ret) {
1242 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize link update, ret:%d", ret);
1243 : 0 : goto l_end;
1244 : : }
1245 : :
1246 : 0 : ret = sxe2_mtu_set(dev, dev->data->mtu);
1247 [ # # ]: 0 : if (ret) {
1248 : 0 : PMD_LOG_ERR(INIT, "Failed to set mtu, ret=%d", ret);
1249 : 0 : goto l_end;
1250 : : }
1251 : :
1252 : 0 : ret = sxe2_mac_addr_init(dev);
1253 [ # # ]: 0 : if (ret != 0) {
1254 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize mac address, ret:%d", ret);
1255 : 0 : goto l_end;
1256 : : }
1257 : :
1258 : 0 : ret = sxe2_mac_default_cfg(dev);
1259 [ # # ]: 0 : if (ret != 0) {
1260 : 0 : PMD_LOG_ERR(INIT, "Failed to configure default mac address, ret:%d", ret);
1261 : 0 : goto l_err;
1262 : : }
1263 : :
1264 : 0 : ret = sxe2_vlan_cfg_init(dev);
1265 [ # # ]: 0 : if (ret) {
1266 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize vlan config, ret:%d", ret);
1267 : 0 : goto l_err;
1268 : : }
1269 : 0 : goto l_end;
1270 : :
1271 : 0 : l_err:
1272 : 0 : sxe2_mac_addr_uinit(dev);
1273 : 0 : (void)sxe2_filter_uinit(dev);
1274 : 0 : l_end:
1275 : 0 : return ret;
1276 : : }
1277 : :
1278 : 0 : void sxe2_eth_uinit(struct rte_eth_dev *dev __rte_unused)
1279 : : {
1280 : 0 : sxe2_mac_addr_uinit(dev);
1281 : 0 : (void)sxe2_filter_uinit(dev);
1282 : 0 : }
1283 : :
1284 : 0 : static void sxe2_drv_dev_caps_set(struct sxe2_adapter *adapter,
1285 : : struct sxe2_drv_dev_caps_resp *dev_caps)
1286 : : {
1287 : 0 : adapter->port_idx = dev_caps->port_idx;
1288 : :
1289 : 0 : adapter->cap_flags = 0;
1290 : :
1291 [ # # ]: 0 : if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_L2)
1292 : 0 : adapter->cap_flags |= SXE2_DEV_CAPS_OFFLOAD_L2;
1293 : :
1294 [ # # ]: 0 : if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_VLAN)
1295 : 0 : adapter->cap_flags |= SXE2_DEV_CAPS_OFFLOAD_VLAN;
1296 : :
1297 [ # # ]: 0 : if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_RSS)
1298 : 0 : adapter->cap_flags |= SXE2_DEV_CAPS_OFFLOAD_RSS;
1299 : :
1300 [ # # ]: 0 : if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_IPSEC)
1301 : 0 : adapter->cap_flags |= SXE2_DEV_CAPS_OFFLOAD_IPSEC;
1302 : :
1303 [ # # ]: 0 : if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_FNAV)
1304 : 0 : adapter->cap_flags |= SXE2_DEV_CAPS_OFFLOAD_FNAV;
1305 : :
1306 [ # # ]: 0 : if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_TM)
1307 : 0 : adapter->cap_flags |= SXE2_DEV_CAPS_OFFLOAD_TM;
1308 : :
1309 [ # # ]: 0 : if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_PTP)
1310 : 0 : adapter->cap_flags |= SXE2_DEV_CAPS_OFFLOAD_PTP;
1311 : :
1312 [ # # ]: 0 : if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_Q_MAP)
1313 : 0 : adapter->cap_flags |= SXE2_DEV_CAPS_OFFLOAD_Q_MAP;
1314 : :
1315 [ # # ]: 0 : if (dev_caps->cap_flags & SXE2_DEV_CAPS_OFFLOAD_FC_STATE)
1316 : 0 : adapter->cap_flags |= SXE2_DEV_CAPS_OFFLOAD_FC_STATE;
1317 : 0 : }
1318 : :
1319 : 0 : static void sxe2_sw_representor_ctx_hw_cap_set(struct sxe2_adapter *adapter,
1320 : : struct sxe2_drv_representor_caps *repr_caps)
1321 : : {
1322 : 0 : adapter->repr_ctxt.nb_vf = repr_caps->cnt_repr_vf;
1323 : 0 : if (adapter->repr_ctxt.nb_vf > 0) {
1324 : 0 : memcpy(adapter->repr_ctxt.repr_vf_id, repr_caps->repr_vf_id,
1325 : 0 : adapter->repr_ctxt.nb_vf * sizeof(struct sxe2_drv_vsi_caps));
1326 : : }
1327 : : }
1328 : :
1329 : 0 : static void sxe2_sw_sched_hw_cap_set(struct sxe2_adapter *adapter,
1330 : : struct sxe2_txsch_caps *txsch_caps)
1331 : : {
1332 : 0 : adapter->sched_ctxt.tm_layers = txsch_caps->layer_cap;
1333 : 0 : adapter->sched_ctxt.root_max_children = txsch_caps->tm_mid_node_num;
1334 : 0 : adapter->sched_ctxt.prio_max = txsch_caps->prio_num;
1335 : 0 : }
1336 : :
1337 : 0 : static int32_t sxe2_func_caps_get(struct sxe2_adapter *adapter)
1338 : : {
1339 : 0 : int32_t ret = -1;
1340 : 0 : struct sxe2_drv_dev_caps_resp dev_caps = {0};
1341 : :
1342 : 0 : ret = sxe2_drv_dev_caps_get(adapter, &dev_caps);
1343 [ # # ]: 0 : if (ret)
1344 : 0 : goto l_end;
1345 : :
1346 : 0 : adapter->dev_type = dev_caps.dev_type;
1347 : :
1348 : 0 : sxe2_drv_dev_caps_set(adapter, &dev_caps);
1349 : :
1350 : 0 : sxe2_sw_queue_ctx_hw_cap_set(adapter, &dev_caps.queue_caps);
1351 : :
1352 : 0 : sxe2_sw_irq_ctx_hw_cap_set(adapter, &dev_caps.msix_caps);
1353 : :
1354 : 0 : sxe2_sw_rss_ctx_hw_cap_set(adapter, &dev_caps.rss_hash_caps);
1355 : :
1356 : 0 : sxe2_sw_vsi_ctx_hw_cap_set(adapter, &dev_caps.vsi_caps);
1357 : :
1358 [ # # ]: 0 : sxe2_sw_representor_ctx_hw_cap_set(adapter, &dev_caps.repr_caps);
1359 : :
1360 : 0 : sxe2_sw_sched_hw_cap_set(adapter, &dev_caps.txsch_caps);
1361 : :
1362 : 0 : l_end:
1363 : 0 : return ret;
1364 : : }
1365 : :
1366 : 0 : static int32_t sxe2_switchdev_info_get(struct sxe2_adapter *adapter)
1367 : : {
1368 : 0 : int32_t ret = 0;
1369 : 0 : struct sxe2_switchdev_info switchdev_info = {0};
1370 : :
1371 : 0 : ret = sxe2_drv_switchdev_info_get(adapter, &switchdev_info);
1372 [ # # ]: 0 : if (ret)
1373 : 0 : goto l_end;
1374 [ # # # # ]: 0 : if (switchdev_info.primary && switchdev_info.representor) {
1375 : 0 : PMD_LOG_ERR(INIT, "device could not be both primary and representor");
1376 : 0 : ret = -ENODEV;
1377 : 0 : goto l_end;
1378 : : }
1379 : 0 : adapter->switchdev_info = switchdev_info;
1380 : 0 : l_end:
1381 : 0 : return ret;
1382 : : }
1383 : :
1384 : 0 : static int32_t sxe2_dev_caps_get(struct sxe2_adapter *adapter)
1385 : : {
1386 : 0 : int32_t ret = -1;
1387 : :
1388 : 0 : ret = sxe2_func_caps_get(adapter);
1389 [ # # ]: 0 : if (ret) {
1390 : 0 : PMD_LOG_ERR(INIT, "get function caps failed, ret=%d", ret);
1391 : 0 : goto l_end;
1392 : : }
1393 : :
1394 : 0 : ret = sxe2_switchdev_info_get(adapter);
1395 [ # # ]: 0 : if (ret)
1396 : 0 : PMD_LOG_ERR(INIT, "get switchdev info failed, ret=%d", ret);
1397 : :
1398 : 0 : l_end:
1399 : 0 : return ret;
1400 : : }
1401 : :
1402 : 0 : uint32_t sxe2_pci_map_read_reg(struct sxe2_adapter *adapter,
1403 : : enum sxe2_pci_map_resource res_type, uint16_t idx_in_func)
1404 : : {
1405 : 0 : void *reg_addr;
1406 : 0 : uint32_t value;
1407 : :
1408 : 0 : reg_addr = sxe2_pci_map_addr_get(adapter, res_type, idx_in_func);
1409 [ # # ]: 0 : if (unlikely(reg_addr == NULL)) {
1410 : 0 : PMD_DEV_LOG_ERR(adapter, DRV, "reg addr:0x%p is error.", reg_addr);
1411 : 0 : value = SXE2_PCI_MAP_INVALID_VAL;
1412 : 0 : goto l_ret;
1413 : : }
1414 : :
1415 : 0 : value = SXE2_PCI_REG_READ(reg_addr);
1416 : :
1417 : 0 : l_ret:
1418 : 0 : return value;
1419 : : }
1420 : :
1421 : 0 : void sxe2_pci_map_write_reg(struct sxe2_adapter *adapter,
1422 : : enum sxe2_pci_map_resource res_type, uint16_t idx_in_func, uint32_t value)
1423 : : {
1424 : 0 : void *reg_addr;
1425 : :
1426 : 0 : reg_addr = sxe2_pci_map_addr_get(adapter, res_type, idx_in_func);
1427 [ # # ]: 0 : if (unlikely(reg_addr == NULL)) {
1428 : 0 : PMD_DEV_LOG_ERR(adapter, DRV, "reg addr:0x%p is error.", reg_addr);
1429 : 0 : goto l_ret;
1430 : : }
1431 : :
1432 : 0 : SXE2_PCI_REG_WRITE_WC(reg_addr, value);
1433 : 0 : l_ret:
1434 : 0 : return;
1435 : : }
1436 : :
1437 : 0 : int32_t sxe2_dev_pci_seg_map(struct sxe2_adapter *adapter,
1438 : : enum sxe2_pci_map_resource res_type,
1439 : : uint64_t org_len,
1440 : : uint64_t org_offset)
1441 : : {
1442 : 0 : struct sxe2_pci_map_bar_info *bar_info = NULL;
1443 : 0 : struct sxe2_pci_map_segment_info *seg_info = NULL;
1444 : 0 : void *map_addr = NULL;
1445 : 0 : int32_t ret = 0;
1446 : 0 : size_t page_size = 0;
1447 : 0 : size_t aligned_len = 0;
1448 : 0 : size_t page_inner_offset = 0;
1449 : 0 : off_t aligned_offset = 0;
1450 : 0 : uint8_t i = 0;
1451 : :
1452 [ # # ]: 0 : if (org_len == 0) {
1453 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Invalid length, ori_len = 0");
1454 : 0 : ret = -EFAULT;
1455 : 0 : goto l_end;
1456 : : }
1457 : :
1458 : 0 : bar_info = sxe2_dev_get_bar_info(adapter, res_type);
1459 [ # # ]: 0 : if (!bar_info) {
1460 : 0 : PMD_LOG_ERR(INIT, "Failed to get bar info, res_type=[%d]", res_type);
1461 : 0 : ret = -EFAULT;
1462 : 0 : goto l_end;
1463 : : }
1464 : 0 : seg_info = bar_info->seg_info;
1465 : :
1466 : 0 : page_size = rte_mem_page_size();
1467 : :
1468 : 0 : aligned_offset = RTE_ALIGN_FLOOR(org_offset, page_size);
1469 : 0 : page_inner_offset = org_offset - aligned_offset;
1470 : 0 : aligned_len = RTE_ALIGN(page_inner_offset + org_len, page_size);
1471 : :
1472 : 0 : map_addr = sxe2_drv_dev_mmap(adapter->cdev, bar_info->bar_idx,
1473 : : aligned_len, aligned_offset);
1474 [ # # ]: 0 : if (!map_addr) {
1475 : 0 : PMD_LOG_ERR(INIT, "Failed to mmap BAR space, type=%d, len=%" PRIu64
1476 : : ", offset=%" PRIu64 ", page_size=%zu",
1477 : : res_type, org_len, org_offset, page_size);
1478 : 0 : ret = -EFAULT;
1479 : 0 : goto l_end;
1480 : : }
1481 : :
1482 [ # # ]: 0 : for (i = 0; i < bar_info->map_cnt; i++) {
1483 [ # # ]: 0 : if (seg_info[i].type != SXE2_PCI_MAP_RES_INVALID)
1484 : 0 : continue;
1485 : 0 : seg_info[i].type = res_type;
1486 : 0 : seg_info[i].addr = map_addr;
1487 : 0 : seg_info[i].page_inner_offset = page_inner_offset;
1488 : 0 : seg_info[i].len = aligned_len;
1489 : 0 : break;
1490 : : }
1491 [ # # ]: 0 : if (i == bar_info->map_cnt) {
1492 : 0 : PMD_LOG_ERR(INIT, "No memory to save resource, res_type=%d", res_type);
1493 : 0 : ret = -ENOMEM;
1494 : 0 : sxe2_drv_dev_munmap(adapter->cdev, map_addr, aligned_len);
1495 : 0 : goto l_end;
1496 : : }
1497 : :
1498 : 0 : l_end:
1499 : 0 : return ret;
1500 : : }
1501 : :
1502 : 0 : static int32_t sxe2_hw_init(struct rte_eth_dev *dev)
1503 : : {
1504 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
1505 : 0 : int32_t ret = -1;
1506 : :
1507 : 0 : PMD_INIT_FUNC_TRACE();
1508 : :
1509 : 0 : ret = sxe2_dev_caps_get(adapter);
1510 [ # # ]: 0 : if (ret)
1511 : 0 : PMD_LOG_ERR(INIT, "Failed to get device caps, ret=[%d]", ret);
1512 : :
1513 : 0 : return ret;
1514 : : }
1515 : :
1516 : 0 : static int32_t sxe2_sw_init(struct rte_eth_dev *dev)
1517 : : {
1518 : 0 : int32_t ret = -1;
1519 : :
1520 : 0 : PMD_INIT_FUNC_TRACE();
1521 : :
1522 : 0 : ret = sxe2_sw_irq_ctxt_init(dev);
1523 [ # # ]: 0 : if (ret) {
1524 : 0 : PMD_LOG_ERR(INIT, "Failed to sw irq ctxt init, ret=[%d]", ret);
1525 : 0 : goto l_end;
1526 : : }
1527 : :
1528 : 0 : l_end:
1529 : 0 : return ret;
1530 : : }
1531 : :
1532 : 0 : static void sxe2_sw_uninit(struct rte_eth_dev *dev)
1533 : : {
1534 : 0 : sxe2_sw_irq_ctxt_uninit(dev);
1535 : 0 : }
1536 : :
1537 : 0 : int32_t sxe2_dev_pci_res_seg_map(struct sxe2_adapter *adapter,
1538 : : uint32_t res_type,
1539 : : uint32_t item_cnt,
1540 : : uint32_t item_base)
1541 : : {
1542 : 0 : struct sxe2_pci_map_addr_info *addr_info = NULL;
1543 : 0 : int32_t ret = 0;
1544 : :
1545 : 0 : addr_info = &adapter->map_ctxt.addr_info[res_type];
1546 [ # # # # ]: 0 : if (!addr_info || addr_info->bar_idx == SXE2_PCI_MAP_BAR_INVALID) {
1547 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Invalid bar index with resource type %d", res_type);
1548 : 0 : ret = -EFAULT;
1549 : 0 : goto l_end;
1550 : : }
1551 : :
1552 : 0 : ret = sxe2_dev_pci_seg_map(adapter, res_type, item_cnt * addr_info->reg_width,
1553 : 0 : addr_info->addr_base + item_base * addr_info->reg_width);
1554 [ # # ]: 0 : if (ret != 0) {
1555 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to map resource, res_type=%d", res_type);
1556 : 0 : goto l_end;
1557 : : }
1558 : 0 : l_end:
1559 : 0 : return ret;
1560 : : }
1561 : :
1562 : 0 : void sxe2_dev_pci_seg_unmap(struct sxe2_adapter *adapter, uint32_t res_type)
1563 : : {
1564 : 0 : struct sxe2_pci_map_bar_info *bar_info = NULL;
1565 : 0 : struct sxe2_pci_map_segment_info *seg_info = NULL;
1566 : 0 : uint32_t i = 0;
1567 : :
1568 : 0 : bar_info = sxe2_dev_get_bar_info(adapter, res_type);
1569 [ # # ]: 0 : if (bar_info == NULL) {
1570 : 0 : PMD_DEV_LOG_WARN(adapter, INIT, "Failed to get bar info, res_type=[%d]", res_type);
1571 : 0 : goto l_end;
1572 : : }
1573 : 0 : seg_info = bar_info->seg_info;
1574 : :
1575 [ # # ]: 0 : for (i = 0; i < bar_info->map_cnt; i++) {
1576 [ # # ]: 0 : if (res_type == seg_info[i].type) {
1577 : 0 : (void)sxe2_drv_dev_munmap(adapter->cdev, seg_info[i].addr,
1578 : : seg_info[i].len);
1579 : 0 : memset(&seg_info[i], 0, sizeof(struct sxe2_pci_map_segment_info));
1580 : : break;
1581 : : }
1582 : : }
1583 : :
1584 : 0 : l_end:
1585 : 0 : return;
1586 : : }
1587 : :
1588 : 0 : static int32_t sxe2_dev_info_init(struct rte_eth_dev *dev)
1589 : : {
1590 : 0 : struct sxe2_adapter *adapter =
1591 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
1592 : 0 : struct rte_pci_device *pci_dev = RTE_CLASS_TO_BUS_DEVICE(dev, *pci_dev);
1593 : 0 : struct sxe2_dev_info *dev_info = &adapter->dev_info;
1594 : 0 : struct sxe2_drv_dev_info_resp dev_info_resp = {0};
1595 : 0 : struct sxe2_drv_dev_fw_info_resp dev_fw_info_resp = {0};
1596 : 0 : int32_t ret = 0;
1597 : :
1598 : 0 : dev_info->pci.bus_devid = pci_dev->addr.devid;
1599 : 0 : dev_info->pci.bus_function = pci_dev->addr.function;
1600 : :
1601 : 0 : ret = sxe2_drv_dev_info_get(adapter, &dev_info_resp);
1602 [ # # ]: 0 : if (ret) {
1603 : 0 : PMD_LOG_ERR(INIT, "Failed to get device info, ret=[%d]", ret);
1604 : 0 : goto l_end;
1605 : : }
1606 : 0 : dev_info->pci.serial_number = dev_info_resp.dsn;
1607 : :
1608 : 0 : ret = sxe2_drv_dev_fw_info_get(adapter, &dev_fw_info_resp);
1609 [ # # ]: 0 : if (ret) {
1610 : 0 : PMD_LOG_ERR(INIT, "Failed to get device fw info, ret=[%d]", ret);
1611 : 0 : goto l_end;
1612 : : }
1613 : 0 : dev_info->fw.build_id = dev_fw_info_resp.build_id;
1614 : 0 : dev_info->fw.fix_version_id = dev_fw_info_resp.fix_version_id;
1615 : 0 : dev_info->fw.sub_version_id = dev_fw_info_resp.sub_version_id;
1616 : 0 : dev_info->fw.main_version_id = dev_fw_info_resp.main_version_id;
1617 : :
1618 [ # # ]: 0 : if (rte_is_valid_assigned_ether_addr((struct rte_ether_addr *)dev_info_resp.mac_addr))
1619 : 0 : rte_ether_addr_copy((struct rte_ether_addr *)dev_info_resp.mac_addr,
1620 : 0 : (struct rte_ether_addr *)dev_info->mac.perm_addr);
1621 : : else
1622 : 0 : rte_eth_random_addr(dev_info->mac.perm_addr);
1623 : :
1624 : 0 : l_end:
1625 : 0 : return ret;
1626 : : }
1627 : :
1628 : 0 : int32_t sxe2_dev_pci_map_init(struct rte_eth_dev *dev)
1629 : : {
1630 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
1631 : 0 : struct rte_pci_device *pci_dev = RTE_CLASS_TO_BUS_DEVICE(dev, *pci_dev);
1632 : 0 : struct sxe2_pci_map_context *map_ctxt = &adapter->map_ctxt;
1633 : 0 : struct sxe2_pci_map_bar_info *bar_info = NULL;
1634 : 0 : struct sxe2_pci_map_segment_info *seg_info = NULL;
1635 : 0 : uint16_t txq_cnt = adapter->q_ctxt.qp_cnt_assign;
1636 : 0 : uint16_t txq_base = adapter->q_ctxt.base_idx_in_pf;
1637 : 0 : uint16_t rxq_cnt = adapter->q_ctxt.qp_cnt_assign;
1638 : 0 : uint16_t irq_cnt = adapter->irq_ctxt.max_cnt_hw;
1639 : 0 : uint16_t irq_base = adapter->irq_ctxt.base_idx_in_func;
1640 : 0 : uint16_t rxq_base = adapter->q_ctxt.base_idx_in_pf;
1641 : 0 : int32_t ret = 0;
1642 : :
1643 : 0 : PMD_INIT_FUNC_TRACE();
1644 : :
1645 : 0 : adapter->dev_info.dev_data = dev->data;
1646 : :
1647 [ # # ]: 0 : if (!pci_dev->mem_resource[0].phys_addr) {
1648 : 0 : PMD_LOG_ERR(INIT, "Physical address not scanned");
1649 : 0 : ret = -ENXIO;
1650 : 0 : goto l_end;
1651 : : }
1652 : :
1653 : 0 : map_ctxt->bar_cnt = 2;
1654 : :
1655 : 0 : bar_info = rte_zmalloc(NULL, sizeof(*bar_info) * map_ctxt->bar_cnt, 0);
1656 [ # # ]: 0 : if (!bar_info) {
1657 : 0 : PMD_LOG_ERR(INIT, "Failed to alloc bar_info");
1658 : 0 : ret = -ENOMEM;
1659 : 0 : goto l_end;
1660 : : }
1661 : 0 : bar_info[0].bar_idx = 0;
1662 : 0 : bar_info[0].map_cnt = SXE2_PCI_MAP_RES_MAX_COUNT;
1663 : 0 : seg_info = rte_zmalloc(NULL, sizeof(*seg_info) * bar_info[0].map_cnt, 0);
1664 [ # # ]: 0 : if (!seg_info) {
1665 : 0 : PMD_LOG_ERR(INIT, "Failed to alloc seg_info");
1666 : 0 : ret = -ENOMEM;
1667 : 0 : goto l_free_bar;
1668 : : }
1669 : :
1670 : 0 : bar_info[0].seg_info = seg_info;
1671 : :
1672 : 0 : bar_info[1].bar_idx = 4;
1673 : 0 : bar_info[1].map_cnt = SXE2_PCI_MAP_RES_MAX_COUNT;
1674 : 0 : seg_info = rte_zmalloc(NULL, sizeof(*seg_info) * bar_info[1].map_cnt, 0);
1675 [ # # ]: 0 : if (!seg_info) {
1676 : 0 : PMD_LOG_ERR(INIT, "Failed to alloc seg_info");
1677 : 0 : ret = -ENOMEM;
1678 : 0 : goto l_free_seg0;
1679 : : }
1680 : :
1681 : 0 : bar_info[1].seg_info = seg_info;
1682 : 0 : map_ctxt->bar_info = bar_info;
1683 : :
1684 [ # # ]: 0 : if (adapter->dev_type == SXE2_DEV_T_VF)
1685 : 0 : map_ctxt->addr_info = sxe2_net_map_addr_info_vf;
1686 : : else
1687 : 0 : map_ctxt->addr_info = sxe2_net_map_addr_info_pf;
1688 : :
1689 : 0 : ret = sxe2_dev_pci_res_seg_map(adapter, SXE2_PCI_MAP_RES_DOORBELL_TX,
1690 : : txq_cnt, txq_base);
1691 [ # # ]: 0 : if (ret) {
1692 : 0 : PMD_LOG_ERR(INIT, "Failed to map txq doorbell addr, ret=%d", ret);
1693 : 0 : goto l_free_seg1;
1694 : : }
1695 : :
1696 : 0 : ret = sxe2_dev_pci_res_seg_map(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL,
1697 : : rxq_cnt, rxq_base);
1698 [ # # ]: 0 : if (ret) {
1699 : 0 : PMD_LOG_ERR(INIT, "Failed to map rxq tail doorbell addr, ret=%d", ret);
1700 : 0 : goto l_free_txq;
1701 : : }
1702 : :
1703 : 0 : ret = sxe2_dev_pci_res_seg_map(adapter, SXE2_PCI_MAP_RES_IRQ_DYN,
1704 : : irq_cnt, irq_base);
1705 [ # # ]: 0 : if (ret) {
1706 : 0 : PMD_LOG_ERR(INIT, "Failed to map irq dyn addr, ret=%d", ret);
1707 : 0 : goto l_free_rxq_tail;
1708 : : }
1709 : :
1710 : 0 : ret = sxe2_dev_pci_res_seg_map(adapter, SXE2_PCI_MAP_RES_IRQ_ITR,
1711 : : irq_cnt, irq_base);
1712 [ # # ]: 0 : if (ret) {
1713 : 0 : PMD_LOG_ERR(INIT, "Failed to map irq itr addr, ret=%d", ret);
1714 : 0 : goto l_free_irq_dyn;
1715 : : }
1716 : :
1717 : 0 : ret = sxe2_dev_pci_res_seg_map(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX,
1718 : : irq_cnt, irq_base);
1719 [ # # ]: 0 : if (ret) {
1720 : 0 : PMD_LOG_ERR(INIT, "Failed to map irq msix addr, ret=%d", ret);
1721 : 0 : goto l_free_irq_itr;
1722 : : }
1723 : 0 : goto l_end;
1724 : :
1725 : 0 : l_free_irq_itr:
1726 : 0 : (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_ITR);
1727 : 0 : l_free_irq_dyn:
1728 : 0 : (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_DYN);
1729 : 0 : l_free_rxq_tail:
1730 : 0 : (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL);
1731 : 0 : l_free_txq:
1732 : 0 : (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_TX);
1733 : 0 : l_free_seg1:
1734 [ # # ]: 0 : if (bar_info[1].seg_info) {
1735 : 0 : rte_free(bar_info[1].seg_info);
1736 : 0 : bar_info[1].seg_info = NULL;
1737 : : }
1738 : 0 : l_free_seg0:
1739 [ # # ]: 0 : if (bar_info[0].seg_info) {
1740 : 0 : rte_free(bar_info[0].seg_info);
1741 : 0 : bar_info[0].seg_info = NULL;
1742 : : }
1743 : 0 : l_free_bar:
1744 : 0 : if (bar_info) {
1745 : 0 : rte_free(bar_info);
1746 : 0 : bar_info = NULL;
1747 : : }
1748 : 0 : l_end:
1749 : 0 : return ret;
1750 : : }
1751 : :
1752 : 0 : void sxe2_dev_pci_map_uinit(struct rte_eth_dev *dev)
1753 : : {
1754 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
1755 : 0 : struct sxe2_pci_map_context *map_ctxt = &adapter->map_ctxt;
1756 : 0 : struct sxe2_pci_map_bar_info *bar_info = NULL;
1757 : 0 : uint8_t i = 0;
1758 : :
1759 : 0 : PMD_INIT_FUNC_TRACE();
1760 : :
1761 : 0 : (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL);
1762 : 0 : (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_DOORBELL_TX);
1763 : 0 : (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_DYN);
1764 : 0 : (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_ITR);
1765 : 0 : (void)sxe2_dev_pci_seg_unmap(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX);
1766 : :
1767 [ # # ]: 0 : if (map_ctxt != NULL && map_ctxt->bar_info != NULL) {
1768 [ # # ]: 0 : for (i = 0; i < map_ctxt->bar_cnt; i++) {
1769 : 0 : bar_info = &map_ctxt->bar_info[i];
1770 [ # # # # ]: 0 : if (bar_info != NULL && bar_info->seg_info != NULL) {
1771 : 0 : rte_free(bar_info->seg_info);
1772 : 0 : bar_info->seg_info = NULL;
1773 : : }
1774 : : }
1775 : 0 : rte_free(map_ctxt->bar_info);
1776 : 0 : map_ctxt->bar_info = NULL;
1777 : : }
1778 : :
1779 : 0 : adapter->dev_info.dev_data = NULL;
1780 : 0 : }
1781 : :
1782 : 0 : static int32_t sxe2_fc_state_init(struct rte_eth_dev *dev)
1783 : : {
1784 : 0 : struct sxe2_adapter *adapter =
1785 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
1786 : 0 : struct sxe2_drv_vsi_fc_get_resp fc_resp = {0};
1787 : 0 : int32_t ret;
1788 : :
1789 [ # # ]: 0 : if (!(adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_FC_STATE)) {
1790 : 0 : adapter->fc_state_ctx.cfg_state = 0;
1791 : 0 : adapter->fc_state_ctx.curr_state = 0;
1792 : 0 : ret = 0;
1793 : 0 : goto l_end;
1794 : : }
1795 : 0 : ret = sxe2_drv_fc_state_get(adapter, &fc_resp);
1796 [ # # ]: 0 : if (ret) {
1797 : 0 : PMD_LOG_ERR(INIT, "Failed to get fc state, ret=[%d]", ret);
1798 : 0 : goto l_end;
1799 : : }
1800 : 0 : adapter->fc_state_ctx.cfg_state = fc_resp.fc_enable;
1801 : 0 : adapter->fc_state_ctx.curr_state = 0;
1802 : 0 : l_end:
1803 : 0 : return ret;
1804 : : }
1805 : 0 : static void sxe2_fc_state_uinit(struct rte_eth_dev *dev)
1806 : : {
1807 : 0 : struct sxe2_adapter *adapter =
1808 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
1809 : 0 : adapter->fc_state_ctx.cfg_state = 0;
1810 : 0 : adapter->fc_state_ctx.curr_state = 0;
1811 : 0 : }
1812 : :
1813 : 0 : uint32_t sxe2_sched_mode_get(struct sxe2_adapter *adapter)
1814 : : {
1815 : 0 : uint32_t ret_mode = SXE2_SCHED_MODE_INVALID;
1816 : 0 : struct sxe2_tm_context *tm_ctxt = &adapter->tm_ctxt;
1817 : :
1818 [ # # ]: 0 : if (adapter->devargs.no_sched_mode)
1819 : : ret_mode = SXE2_SCHED_MODE_NO_SCHED;
1820 [ # # ]: 0 : else if (tm_ctxt->committed)
1821 : : ret_mode = SXE2_SCHED_MODE_TM;
1822 : : else
1823 : 0 : ret_mode = SXE2_SCHED_MODE_DEFAULT;
1824 : :
1825 : 0 : return ret_mode;
1826 : : }
1827 : :
1828 : 0 : static int32_t sxe2_sched_init(struct rte_eth_dev *dev)
1829 : : {
1830 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
1831 : 0 : int32_t ret = 0;
1832 : :
1833 : 0 : adapter->sched_ctxt.adj_lvl = adapter->devargs.sched_layer_mode;
1834 : :
1835 [ # # ]: 0 : if (adapter->devargs.no_sched_mode) {
1836 : 0 : PMD_LOG_DEBUG(DRV, "TM feature will be disabled in high-performance mode.");
1837 : 0 : adapter->cap_flags &= ~(SXE2_DEV_CAPS_OFFLOAD_TM);
1838 : : } else {
1839 : 0 : ret = sxe2_tm_init(dev);
1840 [ # # ]: 0 : if (ret)
1841 : 0 : goto l_end;
1842 : :
1843 : 0 : ret = sxe2_drv_root_tree_alloc(dev);
1844 [ # # ]: 0 : if (ret)
1845 : 0 : goto l_end;
1846 : : }
1847 : :
1848 : 0 : l_end:
1849 : 0 : return ret;
1850 : : }
1851 : :
1852 : 0 : static int32_t sxe2_sched_uinit(struct rte_eth_dev *dev)
1853 : : {
1854 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
1855 : 0 : int32_t ret = 0;
1856 : :
1857 [ # # ]: 0 : if (!adapter->devargs.no_sched_mode) {
1858 : 0 : ret = sxe2_tm_uninit(dev);
1859 [ # # ]: 0 : if (ret) {
1860 : 0 : PMD_LOG_ERR(INIT, "Failed to uninit tm, ret=%d", ret);
1861 : 0 : goto l_end;
1862 : : }
1863 : :
1864 : 0 : ret = sxe2_drv_root_tree_release(dev);
1865 [ # # ]: 0 : if (ret) {
1866 : 0 : PMD_LOG_ERR(INIT, "Failed to release root tree, ret=%d", ret);
1867 : 0 : goto l_end;
1868 : : }
1869 : : }
1870 : :
1871 : 0 : l_end:
1872 : 0 : return ret;
1873 : : }
1874 : :
1875 : 0 : static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
1876 : : __rte_unused struct sxe2_dev_kvargs_info *kvargs)
1877 : : {
1878 : 0 : int32_t ret = 0;
1879 : :
1880 : 0 : PMD_INIT_FUNC_TRACE();
1881 : :
1882 : 0 : sxe2_set_common_function(dev);
1883 : :
1884 : 0 : dev->dev_ops = &sxe2_eth_dev_ops;
1885 : :
1886 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
1887 : 0 : sxe2_rx_mode_func_set(dev);
1888 : 0 : sxe2_tx_mode_func_set(dev);
1889 : 0 : ret = sxe2_mp_init(dev);
1890 [ # # ]: 0 : if (ret != 0)
1891 : 0 : PMD_LOG_ERR(INIT, "Failed to mp init (secondary), ret=%d", ret);
1892 : 0 : goto l_end;
1893 : : }
1894 : :
1895 : 0 : ret = sxe2_args_parse(dev, kvargs);
1896 [ # # ]: 0 : if (ret) {
1897 : 0 : PMD_LOG_ERR(INIT, "Failed to parse devargs, ret=%d", ret);
1898 : 0 : goto l_end;
1899 : : }
1900 : :
1901 : 0 : ret = sxe2_hw_init(dev);
1902 [ # # ]: 0 : if (ret) {
1903 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize hw, ret=[%d]", ret);
1904 : 0 : goto l_end;
1905 : : }
1906 : :
1907 : 0 : ret = sxe2_dev_pci_map_init(dev);
1908 [ # # ]: 0 : if (ret) {
1909 : 0 : PMD_LOG_ERR(INIT, "Failed to pci addr map, ret=[%d]", ret);
1910 : 0 : goto l_end;
1911 : : }
1912 : :
1913 : 0 : ret = sxe2_vsi_init(dev);
1914 [ # # ]: 0 : if (ret) {
1915 : 0 : PMD_LOG_ERR(INIT, "create main vsi failed, ret=%d", ret);
1916 : 0 : goto init_vsi_err;
1917 : : }
1918 : :
1919 : 0 : ret = sxe2_dev_info_init(dev);
1920 [ # # ]: 0 : if (ret) {
1921 : 0 : PMD_LOG_ERR(INIT, "Failed to get device info, ret=[%d]", ret);
1922 : 0 : goto init_dev_info_err;
1923 : : }
1924 : :
1925 : 0 : ret = sxe2_switchdev_init(dev);
1926 [ # # ]: 0 : if (ret) {
1927 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize switchdev mode, ret=[%d]", ret);
1928 : 0 : goto init_switchdev_err;
1929 : : }
1930 : :
1931 : 0 : ret = sxe2_sw_init(dev);
1932 [ # # ]: 0 : if (ret) {
1933 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize sw parameters, ret=[%d]", ret);
1934 : 0 : goto init_sw_err;
1935 : : }
1936 : :
1937 : 0 : ret = sxe2_intr_init(dev);
1938 [ # # ]: 0 : if (ret != 0) {
1939 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize interrupt, ret:%d", ret);
1940 : 0 : goto init_irq_err;
1941 : : }
1942 : :
1943 : 0 : ret = sxe2_eth_init(dev);
1944 [ # # ]: 0 : if (ret) {
1945 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize eth parameters, ret=%d", ret);
1946 : 0 : goto init_eth_err;
1947 : : }
1948 : :
1949 : 0 : ret = sxe2_security_init(dev);
1950 [ # # ]: 0 : if (ret) {
1951 : 0 : PMD_LOG_ERR(INIT, "Failed to initialize security, ret=%d", ret);
1952 : 0 : goto init_security_err;
1953 : : }
1954 : :
1955 : 0 : ret = sxe2_rss_disable(dev);
1956 [ # # ]: 0 : if (ret) {
1957 : 0 : PMD_LOG_ERR(INIT, "Failed to disable rss, ret=%d", ret);
1958 : 0 : goto init_rss_err;
1959 : : }
1960 : :
1961 : 0 : ret = sxe2_flow_init(dev);
1962 [ # # ]: 0 : if (ret) {
1963 : 0 : PMD_LOG_ERR(INIT, "Failed to init flow, ret=%d", ret);
1964 : 0 : goto init_flow_err;
1965 : : }
1966 : :
1967 : 0 : ret = sxe2_fc_state_init(dev);
1968 [ # # ]: 0 : if (ret) {
1969 : 0 : PMD_LOG_ERR(INIT, "Failed to init fc state, ret=%d", ret);
1970 : 0 : goto init_fc_state_err;
1971 : : }
1972 : :
1973 : 0 : ret = sxe2_sched_init(dev);
1974 [ # # ]: 0 : if (ret) {
1975 : 0 : PMD_LOG_ERR(INIT, "Failed to init sched, ret=%d", ret);
1976 : 0 : goto init_sched_err;
1977 : : }
1978 : :
1979 : 0 : ret = sxe2_stats_init(dev);
1980 [ # # ]: 0 : if (ret) {
1981 : 0 : PMD_LOG_ERR(INIT, "Failed to stats init, ret=%d", ret);
1982 : 0 : goto init_xstats_err;
1983 : : }
1984 : :
1985 : 0 : ret = sxe2_mp_init(dev);
1986 [ # # ]: 0 : if (ret) {
1987 : 0 : PMD_LOG_ERR(INIT, "Failed to mp init, ret=%d", ret);
1988 : 0 : goto init_xstats_err;
1989 : : }
1990 : :
1991 : 0 : goto l_end;
1992 : :
1993 : 0 : init_xstats_err:
1994 : 0 : (void)sxe2_sched_uinit(dev);
1995 : 0 : init_sched_err:
1996 : 0 : sxe2_fc_state_uinit(dev);
1997 : 0 : init_fc_state_err:
1998 : 0 : (void)sxe2_flow_uninit(dev);
1999 : 0 : init_flow_err:
2000 : 0 : init_rss_err:
2001 : 0 : sxe2_security_uinit(dev);
2002 : 0 : init_security_err:
2003 : 0 : sxe2_eth_uinit(dev);
2004 : 0 : init_eth_err:
2005 : 0 : sxe2_intr_uninit(dev);
2006 : 0 : init_irq_err:
2007 : 0 : sxe2_sw_uninit(dev);
2008 : 0 : init_sw_err:
2009 : 0 : (void)sxe2_switchdev_uninit(dev);
2010 : 0 : init_switchdev_err:
2011 : 0 : init_dev_info_err:
2012 : 0 : sxe2_vsi_uninit(dev);
2013 : 0 : init_vsi_err:
2014 : 0 : sxe2_dev_pci_map_uinit(dev);
2015 : 0 : l_end:
2016 : 0 : return ret;
2017 : : }
2018 : :
2019 : 0 : static int32_t sxe2_dev_close(struct rte_eth_dev *dev)
2020 : : {
2021 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
2022 : 0 : sxe2_mp_uninit(dev);
2023 : 0 : goto l_end;
2024 : : }
2025 : 0 : sxe2_repr_all_close(dev);
2026 : 0 : (void)sxe2_dev_stop(dev);
2027 : 0 : (void)sxe2_queues_release(dev);
2028 : 0 : sxe2_mp_uninit(dev);
2029 : 0 : (void)sxe2_sched_uinit(dev);
2030 : 0 : (void)sxe2_rss_disable(dev);
2031 : 0 : (void)sxe2_flow_uninit(dev);
2032 : 0 : (void)sxe2_udp_tunnel_port_clear(dev);
2033 : 0 : sxe2_vsi_uninit(dev);
2034 : 0 : sxe2_security_uinit(dev);
2035 : 0 : sxe2_intr_uninit(dev);
2036 : 0 : (void)sxe2_switchdev_uninit(dev);
2037 : 0 : sxe2_sw_uninit(dev);
2038 : 0 : (void)sxe2_switchdev_uninit(dev);
2039 : 0 : sxe2_dev_pci_map_uinit(dev);
2040 : 0 : sxe2_eth_uinit(dev);
2041 : 0 : sxe2_dev_pci_map_uinit(dev);
2042 : 0 : sxe2_free_repr_info(dev);
2043 : 0 : sxe2_fc_state_uinit(dev);
2044 : :
2045 : 0 : l_end:
2046 : 0 : return 0;
2047 : : }
2048 : :
2049 : 0 : static int32_t sxe2_dev_uninit(struct rte_eth_dev *dev)
2050 : : {
2051 : 0 : int32_t ret = 0;
2052 : 0 : int32_t i = 0;
2053 : 0 : struct sxe2_adapter *adapter = NULL;
2054 : 0 : struct rte_eth_dev *rep_dev = NULL;
2055 : :
2056 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
2057 : 0 : goto l_end;
2058 : :
2059 : 0 : adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
2060 [ # # ]: 0 : for (i = 0; i < adapter->repr_ctxt.nb_repr_vf; i++) {
2061 : 0 : rep_dev = adapter->repr_ctxt.vf_rep_eth_dev[i];
2062 [ # # ]: 0 : if (rep_dev) {
2063 : 0 : ret = rep_dev->dev_ops->dev_close(rep_dev);
2064 [ # # ]: 0 : if (ret)
2065 : 0 : goto l_end;
2066 [ # # ]: 0 : if (rep_dev->intr_handle)
2067 : 0 : rte_intr_instance_free(rep_dev->intr_handle);
2068 : 0 : ret = rte_eth_dev_release_port(rep_dev);
2069 [ # # ]: 0 : if (ret)
2070 : 0 : goto l_end;
2071 : 0 : adapter->repr_ctxt.vf_rep_eth_dev[i] = NULL;
2072 : : }
2073 : : }
2074 : :
2075 : 0 : ret = sxe2_dev_close(dev);
2076 [ # # ]: 0 : if (ret) {
2077 : 0 : PMD_LOG_ERR(INIT, "Sxe2 dev close failed, ret=%d", ret);
2078 : 0 : goto l_end;
2079 : : }
2080 : :
2081 : 0 : l_end:
2082 : 0 : return ret;
2083 : : }
2084 : :
2085 : 0 : static int32_t sxe2_eth_pmd_remove(struct sxe2_common_device *cdev)
2086 : : {
2087 : 0 : struct rte_eth_dev *eth_dev;
2088 : 0 : struct rte_pci_device *pci_dev = RTE_BUS_DEVICE(cdev->dev, *pci_dev);
2089 : 0 : int32_t ret = 0;
2090 : :
2091 : 0 : eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
2092 [ # # ]: 0 : if (!eth_dev) {
2093 : 0 : PMD_LOG_INFO(INIT, "Sxe2 dev allocated failed");
2094 : 0 : goto l_end;
2095 : : }
2096 : :
2097 : 0 : ret = sxe2_dev_uninit(eth_dev);
2098 [ # # ]: 0 : if (ret) {
2099 : 0 : PMD_LOG_ERR(INIT, "Sxe2 dev uninit failed, ret=%d", ret);
2100 : 0 : goto l_end;
2101 : : }
2102 : 0 : (void)rte_eth_dev_release_port(eth_dev);
2103 : :
2104 : 0 : l_end:
2105 : 0 : return ret;
2106 : : }
2107 : :
2108 : 0 : static int32_t sxe2_fw_version_string_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
2109 : : {
2110 : 0 : struct sxe2_adapter *adapter =
2111 : 0 : SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
2112 : 0 : struct sxe2_fw_info *fw_info = &adapter->dev_info.fw;
2113 : 0 : int32_t ret_len;
2114 : 0 : int32_t ret;
2115 : :
2116 : 0 : ret_len = snprintf(fw_version, fw_size,
2117 : : "%u.%u.%u.%u",
2118 : 0 : fw_info->main_version_id,
2119 : 0 : fw_info->sub_version_id,
2120 : 0 : fw_info->fix_version_id,
2121 [ # # ]: 0 : fw_info->build_id);
2122 : :
2123 [ # # ]: 0 : if (ret_len < 0) {
2124 : 0 : ret = -EINVAL;
2125 : 0 : goto out;
2126 : : }
2127 : :
2128 : 0 : ret_len += 1;
2129 [ # # ]: 0 : if (fw_size < (size_t)ret_len)
2130 : : ret = -EINVAL;
2131 : : else
2132 : 0 : ret = 0;
2133 : :
2134 : 0 : out:
2135 : 0 : return ret;
2136 : : }
2137 : :
2138 : 0 : static uint16_t sxe2_switchdev_repr_id_encode_get(struct sxe2_switchdev_info *switchdev_info)
2139 : : {
2140 : 0 : enum rte_eth_representor_type type;
2141 : 0 : uint16_t repr = switchdev_info->vf_num;
2142 : 0 : uint32_t pf = switchdev_info->pf_num;
2143 : :
2144 : 0 : switch (switchdev_info->port_name_type) {
2145 : 0 : case SXE2_PHYS_PORT_NAME_TYPE_UPLINK:
2146 [ # # ]: 0 : if (!switchdev_info->representor)
2147 : : return UINT16_MAX;
2148 : 0 : type = RTE_ETH_REPRESENTOR_PF;
2149 : 0 : pf = switchdev_info->mpesw_owner;
2150 : 0 : break;
2151 : : case SXE2_PHYS_PORT_NAME_TYPE_PFVF:
2152 : : default:
2153 : : type = RTE_ETH_REPRESENTOR_VF;
2154 : : break;
2155 : : }
2156 : :
2157 : 0 : return SXE2_REPRESENTOR_ID(pf, type, repr);
2158 : : }
2159 : :
2160 : 0 : static bool sxe2_switchdev_repr_match(struct sxe2_adapter *adapter,
2161 : : struct rte_eth_devargs *req_eth_da)
2162 : : {
2163 : 0 : uint32_t port_idx = 0;
2164 : 0 : uint32_t repr_idx;
2165 [ # # ]: 0 : uint16_t kernel_repr_id = sxe2_switchdev_repr_id_encode_get(&adapter->switchdev_info);
2166 : 0 : uint16_t repr_id;
2167 : :
2168 [ # # # # ]: 0 : switch (req_eth_da->type) {
2169 : : case RTE_ETH_REPRESENTOR_PF:
2170 : : break;
2171 : 0 : case RTE_ETH_REPRESENTOR_VF:
2172 [ # # ]: 0 : if (adapter->switchdev_info.port_name_type !=
2173 : : SXE2_PHYS_PORT_NAME_TYPE_PFVF) {
2174 : 0 : rte_errno = EBUSY;
2175 : 0 : return false;
2176 : : }
2177 : : break;
2178 : 0 : case RTE_ETH_REPRESENTOR_NONE:
2179 : 0 : rte_errno = EBUSY;
2180 : 0 : return false;
2181 : 0 : default:
2182 : 0 : rte_errno = ENOTSUP;
2183 : 0 : return false;
2184 : : }
2185 : :
2186 [ # # ]: 0 : for (repr_idx = 0; repr_idx < req_eth_da->nb_representor_ports; ++repr_idx) {
2187 : 0 : repr_id = SXE2_REPRESENTOR_ID(req_eth_da->ports[port_idx],
2188 : : req_eth_da->type,
2189 : : req_eth_da->representor_ports[repr_idx]);
2190 [ # # ]: 0 : if (repr_id == kernel_repr_id)
2191 : : return true;
2192 : : }
2193 : 0 : rte_errno = EBUSY;
2194 : 0 : return false;
2195 : : }
2196 : :
2197 : 0 : static int32_t sxe2_eth_pmd_probe_pf(struct sxe2_common_device *cdev,
2198 : : struct rte_eth_devargs *req_eth_da __rte_unused,
2199 : : uint16_t owner_id __rte_unused,
2200 : : struct sxe2_dev_kvargs_info *kvargs)
2201 : : {
2202 : 0 : struct rte_pci_device *pci_dev = RTE_BUS_DEVICE(cdev->dev, *pci_dev);
2203 : 0 : struct rte_eth_dev *eth_dev = NULL;
2204 : 0 : struct sxe2_adapter *adapter = NULL;
2205 : 0 : int32_t ret = 0;
2206 : :
2207 : 0 : if (!cdev) {
2208 : : ret = -EINVAL;
2209 : : goto l_end;
2210 : : }
2211 : :
2212 : 0 : eth_dev = rte_eth_dev_pci_allocate(pci_dev, sizeof(struct sxe2_adapter));
2213 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
2214 [ # # ]: 0 : if (eth_dev == NULL) {
2215 : 0 : PMD_LOG_ERR(INIT, "Can not allocate ethdev");
2216 : 0 : ret = -ENOMEM;
2217 : 0 : goto l_end;
2218 : : }
2219 : : } else {
2220 [ # # ]: 0 : if (!eth_dev) {
2221 : 0 : PMD_LOG_DEBUG(INIT, "Can not attach secondary ethdev");
2222 : 0 : ret = -EINVAL;
2223 : 0 : goto l_end;
2224 : : }
2225 : : }
2226 : :
2227 : 0 : adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(eth_dev);
2228 : 0 : adapter->dev_port_id = eth_dev->data->port_id;
2229 [ # # ]: 0 : if (rte_eal_process_type() == RTE_PROC_PRIMARY)
2230 : 0 : adapter->cdev = cdev;
2231 : :
2232 : 0 : ret = sxe2_dev_init(eth_dev, kvargs);
2233 [ # # ]: 0 : if (ret != 0) {
2234 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Sxe2 dev init failed, ret=%d", ret);
2235 : 0 : goto l_release_port;
2236 : : }
2237 : :
2238 [ # # ]: 0 : if (req_eth_da->nb_representor_ports > 0) {
2239 [ # # ]: 0 : if (!adapter->switchdev_info.is_switchdev) {
2240 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Representor requested but Switchdev not enabled");
2241 : 0 : ret = -ENOTSUP;
2242 : 0 : goto l_dev_uinit;
2243 : : }
2244 : :
2245 [ # # ]: 0 : if (!sxe2_switchdev_repr_match(adapter, req_eth_da)) {
2246 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Representor parameters mismatch");
2247 : 0 : ret = -ENOTSUP;
2248 : 0 : goto l_dev_uinit;
2249 : : }
2250 : :
2251 : 0 : ret = sxe2_switchdev_repr_devs_init(adapter, req_eth_da);
2252 [ # # ]: 0 : if (ret) {
2253 : 0 : PMD_DEV_LOG_ERR(adapter, INIT, "Failed to init representor, ret=%d", ret);
2254 : 0 : goto l_dev_uinit;
2255 : : }
2256 : : } else {
2257 : 0 : PMD_DEV_LOG_DEBUG(adapter, INIT, "No representors requested, skipping.");
2258 : : }
2259 : :
2260 : 0 : rte_eth_dev_probing_finish(eth_dev);
2261 : 0 : PMD_DEV_LOG_DEBUG(adapter, INIT, "Sxe2 eth pmd probe successful!");
2262 : 0 : goto l_end;
2263 : :
2264 : 0 : l_dev_uinit:
2265 : 0 : (void)sxe2_dev_uninit(eth_dev);
2266 : 0 : l_release_port:
2267 : 0 : (void)rte_eth_dev_release_port(eth_dev);
2268 : 0 : l_end:
2269 : 0 : return ret;
2270 : : }
2271 : :
2272 : 0 : static int32_t sxe2_parse_eth_devargs(struct rte_device *dev,
2273 : : struct rte_eth_devargs *eth_da)
2274 : : {
2275 : 0 : int32_t ret = 0;
2276 : :
2277 [ # # ]: 0 : if (dev->devargs == NULL)
2278 : : return 0;
2279 : :
2280 [ # # ]: 0 : memset(eth_da, 0, sizeof(*eth_da));
2281 : :
2282 [ # # ]: 0 : if (dev->devargs->cls_str) {
2283 : 0 : ret = rte_eth_devargs_parse(dev->devargs->cls_str,
2284 : : eth_da,
2285 : : 1);
2286 [ # # ]: 0 : if (ret) {
2287 : 0 : PMD_LOG_ERR(INIT, "Failed to parse device arguments: %s",
2288 : : dev->devargs->cls_str);
2289 : 0 : return -rte_errno;
2290 : : }
2291 : : }
2292 : :
2293 [ # # # # ]: 0 : if (eth_da->type == RTE_ETH_REPRESENTOR_NONE && dev->devargs->args) {
2294 : 0 : ret = rte_eth_devargs_parse(dev->devargs->args,
2295 : : eth_da,
2296 : : 1);
2297 [ # # ]: 0 : if (ret) {
2298 : 0 : PMD_LOG_ERR(INIT, "Failed to parse device arguments: %s",
2299 : : dev->devargs->args);
2300 : 0 : return -rte_errno;
2301 : : }
2302 : : }
2303 : :
2304 : : return 0;
2305 : : }
2306 : :
2307 : 0 : static int32_t sxe2_eth_pmd_probe(struct sxe2_common_device *cdev,
2308 : : struct sxe2_dev_kvargs_info *kvargs)
2309 : : {
2310 : 0 : struct rte_eth_devargs eth_da = { .nb_ports = 0 };
2311 : 0 : int32_t ret = 0;
2312 : :
2313 : 0 : ret = sxe2_parse_eth_devargs(cdev->dev, ð_da);
2314 [ # # ]: 0 : if (ret != 0) {
2315 : 0 : ret = -EINVAL;
2316 : 0 : goto l_end;
2317 : : }
2318 : :
2319 : 0 : ret = sxe2_eth_pmd_probe_pf(cdev, ð_da, 0, kvargs);
2320 : :
2321 : 0 : l_end:
2322 : 0 : return ret;
2323 : : }
2324 : :
2325 : : static struct sxe2_class_driver sxe2_eth_pmd = {
2326 : : .drv_class = SXE2_CLASS_TYPE_ETH,
2327 : : .name = "SXE2_ETH_PMD_DRIVER_NAME",
2328 : : .probe = sxe2_eth_pmd_probe,
2329 : : .remove = sxe2_eth_pmd_remove,
2330 : : .id_table = pci_id_sxe2_tbl,
2331 : : .intr_lsc = 1,
2332 : : .intr_rmv = 1,
2333 : : };
2334 : :
2335 : 0 : bool sxe2_ethdev_check(struct rte_eth_dev *dev)
2336 : : {
2337 : 0 : return !strcmp(dev->device->driver->name, "sxe2_pci");
2338 : : }
2339 : :
2340 : 303 : RTE_INIT(rte_sxe2_pmd_init)
2341 : : {
2342 : 303 : sxe2_common_init();
2343 : 303 : sxe2_class_driver_register(&sxe2_eth_pmd);
2344 : 303 : }
2345 : :
2346 : : RTE_PMD_EXPORT_NAME(net_sxe2);
2347 : : RTE_PMD_REGISTER_PCI_TABLE(net_sxe2, pci_id_sxe2_tbl);
2348 : : RTE_PMD_REGISTER_KMOD_DEP(net_sxe2, "* sxe2");
2349 : : RTE_PMD_REGISTER_PARAM_STRING(net_sxe2,
2350 : : "flow-duplicate-pattern=<0|1|2> "
2351 : : "function-flow-direct=<0|1> "
2352 : : "fnav-stat-type=<1|2|3> "
2353 : : "no-sched-mode=<0|1> "
2354 : : "sched-layer-mode=<0-3> "
2355 : : "rx-low-latency=<0|1>");
2356 : :
2357 [ - + ]: 303 : RTE_LOG_REGISTER_SUFFIX(sxe2_log_init, init, NOTICE);
2358 [ - + ]: 303 : RTE_LOG_REGISTER_SUFFIX(sxe2_log_driver, driver, NOTICE);
2359 [ - + ]: 303 : RTE_LOG_REGISTER_SUFFIX(sxe2_log_rx, rx, NOTICE);
2360 [ - + ]: 303 : RTE_LOG_REGISTER_SUFFIX(sxe2_log_tx, tx, NOTICE);
2361 [ - + ]: 303 : RTE_LOG_REGISTER_SUFFIX(sxe2_log_hw, hw, NOTICE);
|