1 /* * SPDX-License-Identifier: BSD-3-Clause
3 * Copyright 2019-2021 NXP
11 #include <ethdev_driver.h>
12 #include <rte_malloc.h>
13 #include <rte_memcpy.h>
14 #include <rte_string_fns.h>
15 #include <rte_cycles.h>
16 #include <rte_kvargs.h>
18 #include <rte_fslmc.h>
19 #include <rte_flow_driver.h>
21 #include "dpaa2_pmd_logs.h"
22 #include <fslmc_vfio.h>
23 #include <dpaa2_hw_pvt.h>
24 #include <dpaa2_hw_mempool.h>
25 #include <dpaa2_hw_dpio.h>
26 #include <mc/fsl_dpmng.h>
27 #include "dpaa2_ethdev.h"
28 #include "dpaa2_sparser.h"
29 #include <fsl_qbman_debug.h>
36 #define PAGE_SIZE (sysconf(_SC_PAGESIZE))
38 #define PAGE_MASK (~(PAGE_SIZE - 1))
40 #define LSX_SERDES_LAN_NB 8
41 #define LSX_SERDES_REG_BASE 0x1ea0000
42 #define LSX_LB_EN_BIT 0x10000000
44 #define CONFIG_SYS_IMMR 0x01000000
46 #define CONFIG_SYS_FSL_GUTS_ADDR (CONFIG_SYS_IMMR + 0x00E00000)
47 #define CONFIG_SYS_FSL_SERDES_ADDR (CONFIG_SYS_IMMR + 0xEA0000)
49 #define FSL_LX_SRDS1_PRTCL_SHIFT 16
50 #define FSL_LX_SRDS2_PRTCL_SHIFT 21
51 #define FSL_LX_SRDS3_PRTCL_SHIFT 26
53 #define FSL_LS_SRDS1_PRTCL_SHIFT 16
54 #define FSL_LS_SRDS2_PRTCL_SHIFT 0
56 #define FSL_LX_SRDS1_REGSR 29
57 #define FSL_LX_SRDS2_REGSR 29
58 #define FSL_LX_SRDS3_REGSR 29
60 #define FSL_LS_SRDS1_REGSR 29
61 #define FSL_LS_SRDS2_REGSR 30
63 #define FSL_LX_SRDS1_PRTCL_MASK 0x001F0000
64 #define FSL_LX_SRDS2_PRTCL_MASK 0x03E00000
65 #define FSL_LX_SRDS3_PRTCL_MASK 0x7C000000
67 #define FSL_LS_SRDS1_PRTCL_MASK 0xFFFF0000
68 #define FSL_LS_SRDS2_PRTCL_MASK 0x0000FFFF
70 struct ccsr_lx_serdes_lan {
71 uint8_t unused1[0xa0];
73 uint8_t unused2[0x100 - 0xa4];
76 struct ccsr_lx_serdes {
77 uint8_t unused0[0x800];
78 struct ccsr_lx_serdes_lan lane[LSX_SERDES_LAN_NB];
81 struct ccsr_ls_serdes {
82 uint8_t unused[0x800];
84 uint32_t gcr0; /* General Control Register 0 */
85 uint32_t gcr1; /* General Control Register 1 */
86 uint32_t gcr2; /* General Control Register 2 */
87 uint32_t ssc0; /* Speed Switch Control 0 */
88 uint32_t rec0; /* Receive Equalization Control 0 */
89 uint32_t rec1; /* Receive Equalization Control 1 */
90 uint32_t tec0; /* Transmit Equalization Control 0 */
91 uint32_t ssc1; /* Speed Switch Control 1 */
95 } lane[LSX_SERDES_LAN_NB];
96 uint8_t res5[0x19fc - 0xa00];
100 uint32_t porsr1; /* POR status 1 */
101 uint32_t porsr2; /* POR status 2 */
102 uint8_t res_008[0x20 - 0x8];
103 uint32_t gpporcr1; /* General-purpose POR configuration */
104 uint32_t gpporcr2; /* General-purpose POR configuration 2 */
107 uint8_t res_030[0x60 - 0x30];
108 uint32_t dcfg_fusesr; /* Fuse status register */
109 uint8_t res_064[0x70 - 0x64];
110 uint32_t devdisr; /* Device disable control 1 */
111 uint32_t devdisr2; /* Device disable control 2 */
112 uint32_t devdisr3; /* Device disable control 3 */
113 uint32_t devdisr4; /* Device disable control 4 */
114 uint32_t devdisr5; /* Device disable control 5 */
115 uint32_t devdisr6; /* Device disable control 6 */
116 uint8_t res_088[0x94 - 0x88];
117 uint32_t coredisr; /* Device disable control 7 */
118 uint8_t res_098[0xa0 - 0x98];
119 uint32_t pvr; /* Processor version */
120 uint32_t svr; /* System version */
121 uint8_t res_0a8[0x100 - 0xa8];
122 uint32_t rcwsr[30]; /* Reset control word status */
124 uint8_t res_178[0x200 - 0x178];
125 uint32_t scratchrw[16]; /* Scratch Read/Write */
126 uint8_t res_240[0x300 - 0x240];
127 uint32_t scratchw1r[4]; /* Scratch Read (Write once) */
128 uint8_t res_310[0x400 - 0x310];
129 uint32_t bootlocptrl; /* Boot location pointer low-order addr */
130 uint32_t bootlocptrh; /* Boot location pointer high-order addr */
131 uint8_t res_408[0x520 - 0x408];
134 uint8_t res_528[0x530 - 0x528]; /* add more registers when needed */
137 uint8_t res_538[0x550 - 0x538]; /* add more registers when needed */
142 uint8_t res_560[0x570 - 0x560]; /* add more registers when needed */
144 uint8_t res_574[0x590 - 0x574]; /* add more registers when needed */
145 uint32_t spare1_amqr;
146 uint32_t spare2_amqr;
147 uint32_t spare3_amqr;
148 uint8_t res_59c[0x620 - 0x59c]; /* add more registers when needed */
149 uint32_t gencr[7]; /* General Control Registers */
150 uint8_t res_63c[0x640 - 0x63c]; /* add more registers when needed */
151 uint32_t cgensr1; /* Core General Status Register */
152 uint8_t res_644[0x660 - 0x644]; /* add more registers when needed */
153 uint32_t cgencr1; /* Core General Control Register */
154 uint8_t res_664[0x740 - 0x664]; /* add more registers when needed */
155 uint32_t tp_ityp[64]; /* Topology Initiator Type Register */
159 } tp_cluster[4]; /* Core cluster n Topology Register */
160 uint8_t res_864[0x920 - 0x864]; /* add more registers when needed */
161 uint32_t ioqoscr[8]; /*I/O Quality of Services Register */
163 uint8_t res_944[0x960 - 0x944]; /* add more registers when needed */
165 uint8_t res_964[0x990 - 0x964]; /* add more registers when needed */
166 uint32_t coredisablesr;
167 uint8_t res_994[0xa00 - 0x994]; /* add more registers when needed */
168 uint32_t sdbgcr; /*Secure Debug Configuration Register */
169 uint8_t res_a04[0xbf8 - 0xa04]; /* add more registers when needed */
172 uint8_t res_858[0x1000 - 0xc00];
175 static void *lsx_ccsr_map_region(uint64_t addr, size_t len)
182 fd = open("/dev/mem", O_RDWR);
184 DPAA2_PMD_ERR("Fail to open /dev/mem");
188 start = addr & PAGE_MASK;
189 offset = addr - start;
190 len = len & PAGE_MASK;
191 if (len < (size_t)PAGE_SIZE)
194 tmp = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, start);
198 if (tmp != MAP_FAILED)
199 return (uint8_t *)tmp + offset;
204 static const uint8_t ls_sd1_prot_idx_map[] = {
205 0x03, 0x05, 0x07, 0x09, 0x0a, 0x0c, 0x0e,
206 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c,
207 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a,
208 0x2b, 0x2d, 0x2e, 0x30, 0x32, 0x33, 0x35,
209 0x37, 0x39, 0x3b, 0x4b, 0x4c, 0x4d, 0x58
212 static const uint8_t ls_sd2_prot_idx_map[] = {
213 0x07, 0x09, 0x0a, 0x0c, 0x0e, 0x10, 0x12,
214 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, 0x20,
215 0x22, 0x24, 0x3d, 0x3f, 0x41, 0x43, 0x45,
216 0x47, 0x49, 0x4f, 0x50, 0x51, 0x52, 0x53,
217 0x54, 0x55, 0x56, 0x57
220 static const uint8_t ls_sd1_eth_loopback_support[][LSX_SERDES_LAN_NB] = {
221 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x03*/
222 {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x05*/
223 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x07*/
224 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x09*/
225 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0a*/
226 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0c*/
227 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0e*/
228 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x10*/
229 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x12*/
230 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x14*/
231 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x16*/
232 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x18*/
233 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1a*/
234 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1c*/
235 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1e*/
236 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x20*/
237 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x22*/
238 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x24*/
239 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x26*/
240 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x28*/
241 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x2a*/
243 {0, 0, 0, 0, 1, 1, 1, 1}, /* 0x2b*/
244 {0, 0, 0, 0, 1, 1, 1, 1}, /* 0x2d*/
245 {0, 0, 0, 0, 1, 1, 1, 1}, /* 0x2e*/
246 {0, 0, 0, 0, 1, 1, 1, 1}, /* 0x30*/
248 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x32*/
249 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x33*/
251 {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x35*/
252 {1, 1, 0, 0, 0, 0, 0, 0}, /* 0x37*/
254 {0, 1, 1, 1, 0, 1, 1, 1}, /* 0x39*/
255 {0, 1, 1, 1, 0, 1, 1, 1}, /* 0x3b*/
256 {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x4b*/
257 {0, 0, 0, 0, 1, 1, 1, 1}, /* 0x4c*/
258 {0, 0, 1, 1, 0, 0, 1, 1}, /* 0x4d*/
259 {0, 0, 0, 0, 0, 0, 1, 1} /* 0x58*/
262 static const uint8_t ls_sd2_eth_loopback_support[][LSX_SERDES_LAN_NB] = {
263 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x07*/
264 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x09*/
265 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0a*/
266 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0c*/
267 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0e*/
268 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x10*/
269 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x12*/
270 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x14*/
271 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x16*/
272 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x18*/
273 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1a*/
274 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1c*/
275 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1e*/
276 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x20*/
277 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x22*/
278 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x24*/
280 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x3d*/
281 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x3f*/
282 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x41*/
283 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x43*/
285 {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x45*/
286 {0, 1, 1, 1, 0, 1, 1, 1}, /* 0x47*/
287 {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x49*/
289 {0, 0, 1, 1, 0, 0, 1, 1}, /* 0x4f*/
290 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x50*/
291 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x51*/
292 {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x52*/
293 {0, 1, 1, 1, 0, 1, 1, 1}, /* 0x53*/
294 {0, 0, 1, 1, 0, 0, 1, 1}, /* 0x54*/
295 {0, 1, 1, 1, 0, 1, 1, 1}, /* 0x55*/
296 {0, 0, 1, 1, 0, 0, 1, 1}, /* 0x56*/
297 {0, 0, 0, 0, 0, 0, 1, 1} /* 0x57*/
305 static const uint8_t lx_sd1_loopback_support[][LSX_SERDES_LAN_NB] = {
306 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0 prot*/
307 {0, 0, 0, 0, 0, 0, 0, 0}, /* 1 prot*/
308 {1, 1, 1, 1, 0, 0, 0, 0}, /* 2 prot*/
309 {1, 1, 1, 1, 0, 0, 0, 0}, /* 3 prot*/
310 {1, 1, 1, 1, 1, 1, 1, 1}, /* 4 prot*/
311 {0, 0, 0, 0, 1, 1, 1, 1}, /* 5 prot*/
312 {1, 1, 1, 1, 1, 1, 1, 1}, /* 6 prot*/
313 {1, 1, 1, 1, 1, 1, 1, 1}, /* 7 prot*/
314 {1, 1, 1, 1, 1, 1, 1, 1}, /* 8 prot*/
315 {0, 1, 1, 1, 0, 1, 1, 1}, /* 9 prot*/
316 {0, 1, 1, 1, 0, 1, 1, 1}, /* 10 prot*/
317 {0, 0, 1, 1, 0, 0, 1, 1}, /* 11 prot*/
318 {0, 0, 0, 0, 0, 0, 1, 1}, /* 12 prot*/
319 {0, 0, 0, 0, 0, 0, 0, 0}, /* 13 prot*/
320 {0, 0, 0, 0, 0, 0, 0, 0}, /* 14 prot*/
321 {0, 0, 0, 0, 0, 0, 0, 0}, /* 15 prot*/
322 {0, 0, 1, 1, 0, 0, 0, 0}, /* 16 prot*/
323 {1, 1, 1, 1, 0, 0, 0, 0}, /* 17 prot*/
324 {1, 1, 1, 1, 1, 1, 1, 1}, /* 18 prot*/
325 {1, 1, 1, 1, 0, 0, 0, 0}, /* 19 prot*/
326 {0, 0, 0, 0, 0, 0, 0, 0}, /* 20 prot*/
327 {1, 1, 1, 1, 0, 0, 1, 1}, /* 21 prot*/
328 {1, 1, 1, 1, 0, 0, 1, 1} /* 22 prot*/
331 static const uint8_t lx_sd2_loopback_support[][LSX_SERDES_LAN_NB] = {
332 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0 prot*/
333 {0, 0, 0, 0, 0, 0, 0, 0}, /* 1 prot*/
334 {0, 0, 0, 0, 0, 0, 0, 0}, /* 2 prot*/
335 {0, 0, 0, 0, 0, 0, 0, 0}, /* 3 prot*/
336 {0, 0, 0, 0, 0, 0, 0, 0}, /* 4 prot*/
337 {0, 0, 0, 0, 0, 0, 0, 0}, /* 5 prot*/
338 {0, 0, 0, 0, 1, 1, 1, 1}, /* 6 prot*/
339 {0, 1, 1, 1, 0, 1, 1, 1}, /* 7 prot*/
340 {0, 0, 0, 0, 0, 0, 1, 1}, /* 8 prot*/
341 {1, 1, 1, 1, 1, 1, 1, 1}, /* 9 prot*/
342 {1, 1, 1, 1, 0, 0, 0, 0}, /* 10 prot*/
343 {0, 1, 1, 1, 0, 1, 1, 1}, /* 11 prot*/
344 {1, 1, 1, 1, 0, 0, 0, 0}, /* 12 prot*/
345 {0, 0, 0, 0, 0, 0, 1, 1}, /* 13 prot*/
346 {0, 0, 1, 1, 0, 0, 1, 1} /* 14 prot*/
350 ls_mac_to_serdes_id(uint8_t mac_id)
352 if (mac_id >= 1 && mac_id <= 8)
354 if (mac_id >= 9 && mac_id <= 16)
361 lx_mac_to_serdes_id(uint8_t mac_id)
363 if (mac_id >= 1 && mac_id <= 10)
365 if (mac_id >= 11 && mac_id <= 18)
372 ls_serdes_cfg_to_idx(uint8_t sd_cfg, int sd_id)
376 if (sd_id == LSX_SERDES_1) {
377 for (i = 0; i < (int)sizeof(ls_sd1_prot_idx_map); i++) {
378 if (ls_sd1_prot_idx_map[i] == sd_cfg)
381 } else if (sd_id == LSX_SERDES_2) {
382 for (i = 0; i < (int)sizeof(ls_sd2_prot_idx_map); i++) {
383 if (ls_sd2_prot_idx_map[i] == sd_cfg)
392 lx_serdes_cfg_to_idx(uint8_t sd_cfg, int sd_id __rte_unused)
398 ls_mac_serdes_lpbk_support(uint16_t mac_id,
399 uint16_t *serdes_id, uint16_t *lan_id)
401 struct ccsr_gur *gur_base =
402 lsx_ccsr_map_region(CONFIG_SYS_FSL_GUTS_ADDR,
403 sizeof(struct ccsr_gur) / 64 * 64 + 64);
406 uint16_t lan_id_tmp = 0;
407 const uint8_t *ls_sd_loopback_support;
409 sd_id = ls_mac_to_serdes_id(mac_id);
411 if (sd_id == LSX_SERDES_1) {
412 sd_cfg = rte_read32(&gur_base->rcwsr[FSL_LS_SRDS1_REGSR - 1]) &
413 FSL_LS_SRDS1_PRTCL_MASK;
414 sd_cfg >>= FSL_LS_SRDS1_PRTCL_SHIFT;
415 } else if (sd_id == LSX_SERDES_2) {
416 sd_cfg = rte_read32(&gur_base->rcwsr[FSL_LS_SRDS2_REGSR - 1]) &
417 FSL_LS_SRDS2_PRTCL_MASK;
418 sd_cfg >>= FSL_LS_SRDS2_PRTCL_SHIFT;
422 sd_cfg = sd_cfg & 0xff;
424 sd_idx = ls_serdes_cfg_to_idx(sd_cfg, sd_id);
426 DPAA2_PMD_ERR("Serdes protocol(0x%02x) does not exist\n",
431 if (sd_id == LSX_SERDES_1) {
432 ls_sd_loopback_support =
433 &ls_sd1_eth_loopback_support[sd_idx][0];
435 ls_sd_loopback_support =
436 &ls_sd2_eth_loopback_support[sd_idx][0];
439 if (sd_id == LSX_SERDES_1)
440 lan_id_tmp = (mac_id - 1);
442 lan_id_tmp = (mac_id - 9);
444 if (lan_id_tmp >= LSX_SERDES_LAN_NB) {
445 DPAA2_PMD_ERR("Invalid serdes lan(%d).", lan_id_tmp);
449 if (!ls_sd_loopback_support[lan_id_tmp])
453 *lan_id = lan_id_tmp;
461 lx_mac_serdes_lpbk_support(uint16_t mac_id,
462 uint16_t *serdes_id, uint16_t *lan_id)
464 struct ccsr_gur *gur_base =
465 lsx_ccsr_map_region(CONFIG_SYS_FSL_GUTS_ADDR,
466 sizeof(struct ccsr_gur) / 64 * 64 + 64);
469 uint16_t lan_id_tmp = 0;
470 const uint8_t *lx_sd_loopback_support;
472 sd_id = lx_mac_to_serdes_id(mac_id);
474 if (sd_id == LSX_SERDES_1) {
475 sd_cfg = rte_read32(&gur_base->rcwsr[FSL_LX_SRDS1_REGSR - 1]) &
476 FSL_LX_SRDS1_PRTCL_MASK;
477 sd_cfg >>= FSL_LX_SRDS1_PRTCL_SHIFT;
478 } else if (sd_id == LSX_SERDES_2) {
479 sd_cfg = rte_read32(&gur_base->rcwsr[FSL_LX_SRDS2_REGSR - 1]) &
480 FSL_LX_SRDS2_PRTCL_MASK;
481 sd_cfg >>= FSL_LX_SRDS2_PRTCL_SHIFT;
485 sd_cfg = sd_cfg & 0xff;
487 sd_idx = lx_serdes_cfg_to_idx(sd_cfg, sd_id);
491 if (sd_id == LSX_SERDES_1)
492 lx_sd_loopback_support = &lx_sd1_loopback_support[sd_idx][0];
494 lx_sd_loopback_support = &lx_sd2_loopback_support[sd_idx][0];
496 if (sd_id == LSX_SERDES_1) {
499 else if (mac_id == 2)
502 lan_id_tmp = (mac_id - 3);
506 else if (mac_id == 12)
508 else if (mac_id == 13)
510 else if (mac_id == 14)
512 else if (mac_id == 15)
514 else if (mac_id == 16)
516 else if (mac_id == 17)
518 else if (mac_id == 18)
524 if (lan_id_tmp >= LSX_SERDES_LAN_NB)
527 if (!lx_sd_loopback_support[lan_id_tmp])
531 *lan_id = lan_id_tmp;
539 ls_serdes_eth_lpbk(uint16_t mac_id, int en)
541 uint16_t serdes_id, lan_id;
544 struct ccsr_ls_serdes *serdes_base;
547 ret = ls_mac_serdes_lpbk_support(mac_id, &serdes_id, &lan_id);
551 serdes_base = lsx_ccsr_map_region(CONFIG_SYS_FSL_SERDES_ADDR +
552 (serdes_id - LSX_SERDES_1) * 0x10000,
553 sizeof(struct ccsr_ls_serdes) / 64 * 64 + 64);
555 DPAA2_PMD_ERR("Serdes register map failed\n");
559 if (serdes_id == LSX_SERDES_1)
560 lan_id = LSX_SERDES_LAN_NB - lan_id - 1;
562 reg = &serdes_base->lane[lan_id].tsc3;
564 data = rte_read32(reg);
566 rte_write32(data | LSX_LB_EN_BIT, reg);
568 rte_write32(data & (~LSX_LB_EN_BIT), reg);
574 lx_serdes_eth_lpbk(uint16_t mac_id, int en)
576 uint16_t serdes_id = 0xffff, lan_id = 0xffff;
579 struct ccsr_lx_serdes *serdes_base;
582 ret = lx_mac_serdes_lpbk_support(mac_id, &serdes_id, &lan_id);
586 serdes_base = lsx_ccsr_map_region(CONFIG_SYS_FSL_SERDES_ADDR +
587 (serdes_id - LSX_SERDES_1) * 0x10000,
588 sizeof(struct ccsr_lx_serdes) / 64 * 64 + 64);
590 DPAA2_PMD_ERR("Serdes register map failed\n");
594 if (serdes_id == LSX_SERDES_1)
595 lan_id = LSX_SERDES_LAN_NB - lan_id - 1;
597 reg = &serdes_base->lane[lan_id].lnatcsr0;
599 data = rte_read32(reg);
601 rte_write32(data | LSX_LB_EN_BIT, reg);
603 rte_write32(data & (~LSX_LB_EN_BIT), reg);
608 /* Configure dpaa2 port as recycle port */
610 dpaa2_dev_recycle_config(struct rte_eth_dev *eth_dev)
612 struct rte_device *dev = eth_dev->device;
613 struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
614 struct rte_dpaa2_device *dpaa2_dev =
615 container_of(dev, struct rte_dpaa2_device, device);
616 struct fsl_mc_io *dpni_dev = eth_dev->process_private;
617 struct dpni_port_cfg port_cfg;
620 if (priv->flags & DPAA2_TX_LOOPBACK_MODE) {
621 DPAA2_PMD_INFO("%s has been configured recycle device.",
622 eth_dev->data->name);
627 if (dpaa2_dev->ep_dev_type == DPAA2_MAC) {
628 /** For dpmac-dpni connection,
629 * try setting serdes loopback as recycle device at first.
631 if (dpaa2_svr_family == SVR_LS2088A) {
632 ret = ls_serdes_eth_lpbk(dpaa2_dev->ep_object_id, 1);
634 priv->flags |= DPAA2_TX_SERDES_LOOPBACK_MODE;
637 } else if (dpaa2_svr_family == SVR_LX2160A) {
638 ret = lx_serdes_eth_lpbk(dpaa2_dev->ep_object_id, 1);
640 priv->flags |= DPAA2_TX_SERDES_LOOPBACK_MODE;
644 DPAA2_PMD_DEBUG("Serdes loopback not support SoC(0x%08x)",
648 /** If serdes loopback is not supported for this mac,
649 * trying set mac loopback.
652 port_cfg.loopback_en = 1;
653 ret = dpni_set_port_cfg(dpni_dev, CMD_PRI_LOW,
655 DPNI_PORT_CFG_LOOPBACK,
658 DPAA2_PMD_ERR("Error(%d) to enable loopback", ret);
662 priv->flags |= DPAA2_TX_MAC_LOOPBACK_MODE;
667 if (dpaa2_dev->ep_dev_type == DPAA2_ETH &&
668 dpaa2_dev->object_id == dpaa2_dev->ep_object_id) {
669 priv->flags |= DPAA2_TX_DPNI_LOOPBACK_MODE;
678 dpaa2_dev_recycle_deconfig(struct rte_eth_dev *eth_dev)
680 struct rte_device *dev = eth_dev->device;
681 struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
682 struct rte_dpaa2_device *dpaa2_dev =
683 container_of(dev, struct rte_dpaa2_device, device);
684 struct fsl_mc_io *dpni_dev = eth_dev->process_private;
685 struct dpni_port_cfg port_cfg;
688 if (!(priv->flags & DPAA2_TX_LOOPBACK_MODE))
691 if (priv->flags & DPAA2_TX_SERDES_LOOPBACK_MODE) {
692 if (dpaa2_svr_family == SVR_LS2088A) {
693 ret = ls_serdes_eth_lpbk(dpaa2_dev->ep_object_id, 0);
695 DPAA2_PMD_WARN("Error(%d) to disable Serdes loopback",
698 priv->flags &= ~DPAA2_TX_SERDES_LOOPBACK_MODE;
700 } else if (dpaa2_svr_family == SVR_LX2160A) {
701 ret = lx_serdes_eth_lpbk(dpaa2_dev->ep_object_id, 0);
703 DPAA2_PMD_WARN("Error(%d) to disable Serdes loopback",
706 priv->flags &= ~DPAA2_TX_SERDES_LOOPBACK_MODE;
709 DPAA2_PMD_DEBUG("Serdes loopback not support SoC(0x%08x)",
714 if (priv->flags & DPAA2_TX_MAC_LOOPBACK_MODE) {
715 port_cfg.loopback_en = 0;
716 ret = dpni_set_port_cfg(dpni_dev, CMD_PRI_LOW,
718 DPNI_PORT_CFG_LOOPBACK,
721 DPAA2_PMD_ERR("Error(%d) to disable TX mac loopback",
724 priv->flags &= ~DPAA2_TX_MAC_LOOPBACK_MODE;
728 if (priv->flags & DPAA2_TX_DPNI_LOOPBACK_MODE)
729 priv->flags &= ~DPAA2_TX_DPNI_LOOPBACK_MODE;
735 dpaa2_dev_recycle_qp_setup(struct rte_dpaa2_device *dpaa2_dev,
736 uint16_t qidx, uint64_t cntx,
737 eth_rx_burst_t tx_lpbk, eth_tx_burst_t rx_lpbk,
738 struct dpaa2_queue **txq,
739 struct dpaa2_queue **rxq)
741 struct rte_eth_dev *dev;
742 struct rte_eth_dev_data *data;
743 struct dpaa2_queue *txq_tmp;
744 struct dpaa2_queue *rxq_tmp;
745 struct dpaa2_dev_priv *priv;
747 dev = dpaa2_dev->eth_dev;
749 priv = data->dev_private;
751 if (!(priv->flags & DPAA2_TX_LOOPBACK_MODE) &&
752 (tx_lpbk || rx_lpbk)) {
753 DPAA2_PMD_ERR("%s is NOT recycle device!", data->name);
758 if (qidx >= data->nb_rx_queues || qidx >= data->nb_tx_queues)
761 rte_spinlock_lock(&priv->lpbk_qp_lock);
764 dev->tx_pkt_burst = tx_lpbk;
767 dev->rx_pkt_burst = rx_lpbk;
769 txq_tmp = data->tx_queues[qidx];
770 txq_tmp->lpbk_cntx = cntx;
771 rxq_tmp = data->rx_queues[qidx];
772 rxq_tmp->lpbk_cntx = cntx;
779 rte_spinlock_unlock(&priv->lpbk_qp_lock);