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>
35 #define PAGE_SIZE (sysconf(_SC_PAGESIZE))
36 #define PAGE_MASK (~(PAGE_SIZE - 1))
38 #define LSX_SERDES_LAN_NB 8
39 #define LSX_SERDES_REG_BASE 0x1ea0000
40 #define LSX_LB_EN_BIT 0x10000000
42 #define CONFIG_SYS_IMMR 0x01000000
44 #define CONFIG_SYS_FSL_GUTS_ADDR (CONFIG_SYS_IMMR + 0x00E00000)
45 #define CONFIG_SYS_FSL_SERDES_ADDR (CONFIG_SYS_IMMR + 0xEA0000)
47 #define FSL_LX_SRDS1_PRTCL_SHIFT 16
48 #define FSL_LX_SRDS2_PRTCL_SHIFT 21
49 #define FSL_LX_SRDS3_PRTCL_SHIFT 26
51 #define FSL_LS_SRDS1_PRTCL_SHIFT 16
52 #define FSL_LS_SRDS2_PRTCL_SHIFT 0
54 #define FSL_LX_SRDS1_REGSR 29
55 #define FSL_LX_SRDS2_REGSR 29
56 #define FSL_LX_SRDS3_REGSR 29
58 #define FSL_LS_SRDS1_REGSR 29
59 #define FSL_LS_SRDS2_REGSR 30
61 #define FSL_LX_SRDS1_PRTCL_MASK 0x001F0000
62 #define FSL_LX_SRDS2_PRTCL_MASK 0x03E00000
63 #define FSL_LX_SRDS3_PRTCL_MASK 0x7C000000
65 #define FSL_LS_SRDS1_PRTCL_MASK 0xFFFF0000
66 #define FSL_LS_SRDS2_PRTCL_MASK 0x0000FFFF
68 struct ccsr_lx_serdes_lan {
69 uint8_t unused1[0xa0];
71 uint8_t unused2[0x100 - 0xa4];
74 struct ccsr_lx_serdes {
75 uint8_t unused0[0x800];
76 struct ccsr_lx_serdes_lan lane[LSX_SERDES_LAN_NB];
79 struct ccsr_ls_serdes {
80 uint8_t unused[0x800];
82 uint32_t gcr0; /* General Control Register 0 */
83 uint32_t gcr1; /* General Control Register 1 */
84 uint32_t gcr2; /* General Control Register 2 */
85 uint32_t ssc0; /* Speed Switch Control 0 */
86 uint32_t rec0; /* Receive Equalization Control 0 */
87 uint32_t rec1; /* Receive Equalization Control 1 */
88 uint32_t tec0; /* Transmit Equalization Control 0 */
89 uint32_t ssc1; /* Speed Switch Control 1 */
93 } lane[LSX_SERDES_LAN_NB];
94 uint8_t res5[0x19fc - 0xa00];
98 uint32_t porsr1; /* POR status 1 */
99 uint32_t porsr2; /* POR status 2 */
100 uint8_t res_008[0x20 - 0x8];
101 uint32_t gpporcr1; /* General-purpose POR configuration */
102 uint32_t gpporcr2; /* General-purpose POR configuration 2 */
105 uint8_t res_030[0x60 - 0x30];
106 uint32_t dcfg_fusesr; /* Fuse status register */
107 uint8_t res_064[0x70 - 0x64];
108 uint32_t devdisr; /* Device disable control 1 */
109 uint32_t devdisr2; /* Device disable control 2 */
110 uint32_t devdisr3; /* Device disable control 3 */
111 uint32_t devdisr4; /* Device disable control 4 */
112 uint32_t devdisr5; /* Device disable control 5 */
113 uint32_t devdisr6; /* Device disable control 6 */
114 uint8_t res_088[0x94 - 0x88];
115 uint32_t coredisr; /* Device disable control 7 */
116 uint8_t res_098[0xa0 - 0x98];
117 uint32_t pvr; /* Processor version */
118 uint32_t svr; /* System version */
119 uint8_t res_0a8[0x100 - 0xa8];
120 uint32_t rcwsr[30]; /* Reset control word status */
122 uint8_t res_178[0x200 - 0x178];
123 uint32_t scratchrw[16]; /* Scratch Read/Write */
124 uint8_t res_240[0x300 - 0x240];
125 uint32_t scratchw1r[4]; /* Scratch Read (Write once) */
126 uint8_t res_310[0x400 - 0x310];
127 uint32_t bootlocptrl; /* Boot location pointer low-order addr */
128 uint32_t bootlocptrh; /* Boot location pointer high-order addr */
129 uint8_t res_408[0x520 - 0x408];
132 uint8_t res_528[0x530 - 0x528]; /* add more registers when needed */
135 uint8_t res_538[0x550 - 0x538]; /* add more registers when needed */
140 uint8_t res_560[0x570 - 0x560]; /* add more registers when needed */
142 uint8_t res_574[0x590 - 0x574]; /* add more registers when needed */
143 uint32_t spare1_amqr;
144 uint32_t spare2_amqr;
145 uint32_t spare3_amqr;
146 uint8_t res_59c[0x620 - 0x59c]; /* add more registers when needed */
147 uint32_t gencr[7]; /* General Control Registers */
148 uint8_t res_63c[0x640 - 0x63c]; /* add more registers when needed */
149 uint32_t cgensr1; /* Core General Status Register */
150 uint8_t res_644[0x660 - 0x644]; /* add more registers when needed */
151 uint32_t cgencr1; /* Core General Control Register */
152 uint8_t res_664[0x740 - 0x664]; /* add more registers when needed */
153 uint32_t tp_ityp[64]; /* Topology Initiator Type Register */
157 } tp_cluster[4]; /* Core cluster n Topology Register */
158 uint8_t res_864[0x920 - 0x864]; /* add more registers when needed */
159 uint32_t ioqoscr[8]; /*I/O Quality of Services Register */
161 uint8_t res_944[0x960 - 0x944]; /* add more registers when needed */
163 uint8_t res_964[0x990 - 0x964]; /* add more registers when needed */
164 uint32_t coredisablesr;
165 uint8_t res_994[0xa00 - 0x994]; /* add more registers when needed */
166 uint32_t sdbgcr; /*Secure Debug Configuration Register */
167 uint8_t res_a04[0xbf8 - 0xa04]; /* add more registers when needed */
170 uint8_t res_858[0x1000 - 0xc00];
173 static void *lsx_ccsr_map_region(uint64_t addr, size_t len)
180 fd = open("/dev/mem", O_RDWR);
182 DPAA2_PMD_ERR("Fail to open /dev/mem");
186 start = addr & PAGE_MASK;
187 offset = addr - start;
188 len = len & PAGE_MASK;
189 if (len < (size_t)PAGE_SIZE)
192 tmp = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, start);
196 if (tmp != MAP_FAILED)
197 return (uint8_t *)tmp + offset;
202 static const uint8_t ls_sd1_prot_idx_map[] = {
203 0x03, 0x05, 0x07, 0x09, 0x0a, 0x0c, 0x0e,
204 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c,
205 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a,
206 0x2b, 0x2d, 0x2e, 0x30, 0x32, 0x33, 0x35,
207 0x37, 0x39, 0x3b, 0x4b, 0x4c, 0x4d, 0x58
210 static const uint8_t ls_sd2_prot_idx_map[] = {
211 0x07, 0x09, 0x0a, 0x0c, 0x0e, 0x10, 0x12,
212 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, 0x20,
213 0x22, 0x24, 0x3d, 0x3f, 0x41, 0x43, 0x45,
214 0x47, 0x49, 0x4f, 0x50, 0x51, 0x52, 0x53,
215 0x54, 0x55, 0x56, 0x57
218 static const uint8_t ls_sd1_eth_loopback_support[][LSX_SERDES_LAN_NB] = {
219 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x03*/
220 {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x05*/
221 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x07*/
222 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x09*/
223 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0a*/
224 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0c*/
225 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0e*/
226 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x10*/
227 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x12*/
228 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x14*/
229 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x16*/
230 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x18*/
231 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1a*/
232 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1c*/
233 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1e*/
234 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x20*/
235 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x22*/
236 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x24*/
237 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x26*/
238 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x28*/
239 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x2a*/
241 {0, 0, 0, 0, 1, 1, 1, 1}, /* 0x2b*/
242 {0, 0, 0, 0, 1, 1, 1, 1}, /* 0x2d*/
243 {0, 0, 0, 0, 1, 1, 1, 1}, /* 0x2e*/
244 {0, 0, 0, 0, 1, 1, 1, 1}, /* 0x30*/
246 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x32*/
247 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x33*/
249 {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x35*/
250 {1, 1, 0, 0, 0, 0, 0, 0}, /* 0x37*/
252 {0, 1, 1, 1, 0, 1, 1, 1}, /* 0x39*/
253 {0, 1, 1, 1, 0, 1, 1, 1}, /* 0x3b*/
254 {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x4b*/
255 {0, 0, 0, 0, 1, 1, 1, 1}, /* 0x4c*/
256 {0, 0, 1, 1, 0, 0, 1, 1}, /* 0x4d*/
257 {0, 0, 0, 0, 0, 0, 1, 1} /* 0x58*/
260 static const uint8_t ls_sd2_eth_loopback_support[][LSX_SERDES_LAN_NB] = {
261 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x07*/
262 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x09*/
263 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0a*/
264 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0c*/
265 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x0e*/
266 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x10*/
267 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x12*/
268 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x14*/
269 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x16*/
270 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x18*/
271 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1a*/
272 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1c*/
273 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x1e*/
274 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x20*/
275 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x22*/
276 {1, 1, 1, 1, 1, 1, 1, 1}, /* 0x24*/
278 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x3d*/
279 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x3f*/
280 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x41*/
281 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x43*/
283 {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x45*/
284 {0, 1, 1, 1, 0, 1, 1, 1}, /* 0x47*/
285 {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x49*/
287 {0, 0, 1, 1, 0, 0, 1, 1}, /* 0x4f*/
288 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x50*/
289 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0x51*/
290 {1, 1, 1, 1, 0, 0, 0, 0}, /* 0x52*/
291 {0, 1, 1, 1, 0, 1, 1, 1}, /* 0x53*/
292 {0, 0, 1, 1, 0, 0, 1, 1}, /* 0x54*/
293 {0, 1, 1, 1, 0, 1, 1, 1}, /* 0x55*/
294 {0, 0, 1, 1, 0, 0, 1, 1}, /* 0x56*/
295 {0, 0, 0, 0, 0, 0, 1, 1} /* 0x57*/
303 static const uint8_t lx_sd1_loopback_support[][LSX_SERDES_LAN_NB] = {
304 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0 prot*/
305 {0, 0, 0, 0, 0, 0, 0, 0}, /* 1 prot*/
306 {1, 1, 1, 1, 0, 0, 0, 0}, /* 2 prot*/
307 {1, 1, 1, 1, 0, 0, 0, 0}, /* 3 prot*/
308 {1, 1, 1, 1, 1, 1, 1, 1}, /* 4 prot*/
309 {0, 0, 0, 0, 1, 1, 1, 1}, /* 5 prot*/
310 {1, 1, 1, 1, 1, 1, 1, 1}, /* 6 prot*/
311 {1, 1, 1, 1, 1, 1, 1, 1}, /* 7 prot*/
312 {1, 1, 1, 1, 1, 1, 1, 1}, /* 8 prot*/
313 {0, 1, 1, 1, 0, 1, 1, 1}, /* 9 prot*/
314 {0, 1, 1, 1, 0, 1, 1, 1}, /* 10 prot*/
315 {0, 0, 1, 1, 0, 0, 1, 1}, /* 11 prot*/
316 {0, 0, 0, 0, 0, 0, 1, 1}, /* 12 prot*/
317 {0, 0, 0, 0, 0, 0, 0, 0}, /* 13 prot*/
318 {0, 0, 0, 0, 0, 0, 0, 0}, /* 14 prot*/
319 {0, 0, 0, 0, 0, 0, 0, 0}, /* 15 prot*/
320 {0, 0, 1, 1, 0, 0, 0, 0}, /* 16 prot*/
321 {1, 1, 1, 1, 0, 0, 0, 0}, /* 17 prot*/
322 {1, 1, 1, 1, 1, 1, 1, 1}, /* 18 prot*/
323 {1, 1, 1, 1, 0, 0, 0, 0}, /* 19 prot*/
324 {0, 0, 0, 0, 0, 0, 0, 0}, /* 20 prot*/
325 {1, 1, 1, 1, 0, 0, 1, 1}, /* 21 prot*/
326 {1, 1, 1, 1, 0, 0, 1, 1} /* 22 prot*/
329 static const uint8_t lx_sd2_loopback_support[][LSX_SERDES_LAN_NB] = {
330 {0, 0, 0, 0, 0, 0, 0, 0}, /* 0 prot*/
331 {0, 0, 0, 0, 0, 0, 0, 0}, /* 1 prot*/
332 {0, 0, 0, 0, 0, 0, 0, 0}, /* 2 prot*/
333 {0, 0, 0, 0, 0, 0, 0, 0}, /* 3 prot*/
334 {0, 0, 0, 0, 0, 0, 0, 0}, /* 4 prot*/
335 {0, 0, 0, 0, 0, 0, 0, 0}, /* 5 prot*/
336 {0, 0, 0, 0, 1, 1, 1, 1}, /* 6 prot*/
337 {0, 1, 1, 1, 0, 1, 1, 1}, /* 7 prot*/
338 {0, 0, 0, 0, 0, 0, 1, 1}, /* 8 prot*/
339 {1, 1, 1, 1, 1, 1, 1, 1}, /* 9 prot*/
340 {1, 1, 1, 1, 0, 0, 0, 0}, /* 10 prot*/
341 {0, 1, 1, 1, 0, 1, 1, 1}, /* 11 prot*/
342 {1, 1, 1, 1, 0, 0, 0, 0}, /* 12 prot*/
343 {0, 0, 0, 0, 0, 0, 1, 1}, /* 13 prot*/
344 {0, 0, 1, 1, 0, 0, 1, 1} /* 14 prot*/
348 ls_mac_to_serdes_id(uint8_t mac_id)
350 if (mac_id >= 1 && mac_id <= 8)
352 if (mac_id >= 9 && mac_id <= 16)
359 lx_mac_to_serdes_id(uint8_t mac_id)
361 if (mac_id >= 1 && mac_id <= 10)
363 if (mac_id >= 11 && mac_id <= 18)
370 ls_serdes_cfg_to_idx(uint8_t sd_cfg, int sd_id)
374 if (sd_id == LSX_SERDES_1) {
375 for (i = 0; i < (int)sizeof(ls_sd1_prot_idx_map); i++) {
376 if (ls_sd1_prot_idx_map[i] == sd_cfg)
379 } else if (sd_id == LSX_SERDES_2) {
380 for (i = 0; i < (int)sizeof(ls_sd2_prot_idx_map); i++) {
381 if (ls_sd2_prot_idx_map[i] == sd_cfg)
390 lx_serdes_cfg_to_idx(uint8_t sd_cfg, int sd_id __rte_unused)
396 ls_mac_serdes_lpbk_support(uint16_t mac_id,
397 uint16_t *serdes_id, uint16_t *lan_id)
399 struct ccsr_gur *gur_base =
400 lsx_ccsr_map_region(CONFIG_SYS_FSL_GUTS_ADDR,
401 sizeof(struct ccsr_gur) / 64 * 64 + 64);
404 uint16_t lan_id_tmp = 0;
405 const uint8_t *ls_sd_loopback_support;
407 sd_id = ls_mac_to_serdes_id(mac_id);
409 if (sd_id == LSX_SERDES_1) {
410 sd_cfg = rte_read32(&gur_base->rcwsr[FSL_LS_SRDS1_REGSR - 1]) &
411 FSL_LS_SRDS1_PRTCL_MASK;
412 sd_cfg >>= FSL_LS_SRDS1_PRTCL_SHIFT;
413 } else if (sd_id == LSX_SERDES_2) {
414 sd_cfg = rte_read32(&gur_base->rcwsr[FSL_LS_SRDS2_REGSR - 1]) &
415 FSL_LS_SRDS2_PRTCL_MASK;
416 sd_cfg >>= FSL_LS_SRDS2_PRTCL_SHIFT;
420 sd_cfg = sd_cfg & 0xff;
422 sd_idx = ls_serdes_cfg_to_idx(sd_cfg, sd_id);
424 DPAA2_PMD_ERR("Serdes protocol(0x%02x) does not exist\n",
429 if (sd_id == LSX_SERDES_1) {
430 ls_sd_loopback_support =
431 &ls_sd1_eth_loopback_support[sd_idx][0];
433 ls_sd_loopback_support =
434 &ls_sd2_eth_loopback_support[sd_idx][0];
437 if (sd_id == LSX_SERDES_1)
438 lan_id_tmp = (mac_id - 1);
440 lan_id_tmp = (mac_id - 9);
442 if (lan_id_tmp >= LSX_SERDES_LAN_NB) {
443 DPAA2_PMD_ERR("Invalid serdes lan(%d).", lan_id_tmp);
447 if (!ls_sd_loopback_support[lan_id_tmp])
451 *lan_id = lan_id_tmp;
459 lx_mac_serdes_lpbk_support(uint16_t mac_id,
460 uint16_t *serdes_id, uint16_t *lan_id)
462 struct ccsr_gur *gur_base =
463 lsx_ccsr_map_region(CONFIG_SYS_FSL_GUTS_ADDR,
464 sizeof(struct ccsr_gur) / 64 * 64 + 64);
467 uint16_t lan_id_tmp = 0;
468 const uint8_t *lx_sd_loopback_support;
470 sd_id = lx_mac_to_serdes_id(mac_id);
472 if (sd_id == LSX_SERDES_1) {
473 sd_cfg = rte_read32(&gur_base->rcwsr[FSL_LX_SRDS1_REGSR - 1]) &
474 FSL_LX_SRDS1_PRTCL_MASK;
475 sd_cfg >>= FSL_LX_SRDS1_PRTCL_SHIFT;
476 } else if (sd_id == LSX_SERDES_2) {
477 sd_cfg = rte_read32(&gur_base->rcwsr[FSL_LX_SRDS2_REGSR - 1]) &
478 FSL_LX_SRDS2_PRTCL_MASK;
479 sd_cfg >>= FSL_LX_SRDS2_PRTCL_SHIFT;
483 sd_cfg = sd_cfg & 0xff;
485 sd_idx = lx_serdes_cfg_to_idx(sd_cfg, sd_id);
489 if (sd_id == LSX_SERDES_1)
490 lx_sd_loopback_support = &lx_sd1_loopback_support[sd_idx][0];
492 lx_sd_loopback_support = &lx_sd2_loopback_support[sd_idx][0];
494 if (sd_id == LSX_SERDES_1) {
497 else if (mac_id == 2)
500 lan_id_tmp = (mac_id - 3);
504 else if (mac_id == 12)
506 else if (mac_id == 13)
508 else if (mac_id == 14)
510 else if (mac_id == 15)
512 else if (mac_id == 16)
514 else if (mac_id == 17)
516 else if (mac_id == 18)
522 if (lan_id_tmp >= LSX_SERDES_LAN_NB)
525 if (!lx_sd_loopback_support[lan_id_tmp])
529 *lan_id = lan_id_tmp;
537 ls_serdes_eth_lpbk(uint16_t mac_id, int en)
539 uint16_t serdes_id, lan_id;
542 struct ccsr_ls_serdes *serdes_base;
545 ret = ls_mac_serdes_lpbk_support(mac_id, &serdes_id, &lan_id);
549 serdes_base = lsx_ccsr_map_region(CONFIG_SYS_FSL_SERDES_ADDR +
550 (serdes_id - LSX_SERDES_1) * 0x10000,
551 sizeof(struct ccsr_ls_serdes) / 64 * 64 + 64);
553 DPAA2_PMD_ERR("Serdes register map failed\n");
557 if (serdes_id == LSX_SERDES_1)
558 lan_id = LSX_SERDES_LAN_NB - lan_id - 1;
560 reg = &serdes_base->lane[lan_id].tsc3;
562 data = rte_read32(reg);
564 rte_write32(data | LSX_LB_EN_BIT, reg);
566 rte_write32(data & (~LSX_LB_EN_BIT), reg);
572 lx_serdes_eth_lpbk(uint16_t mac_id, int en)
574 uint16_t serdes_id = 0xffff, lan_id = 0xffff;
577 struct ccsr_lx_serdes *serdes_base;
580 ret = lx_mac_serdes_lpbk_support(mac_id, &serdes_id, &lan_id);
584 serdes_base = lsx_ccsr_map_region(CONFIG_SYS_FSL_SERDES_ADDR +
585 (serdes_id - LSX_SERDES_1) * 0x10000,
586 sizeof(struct ccsr_lx_serdes) / 64 * 64 + 64);
588 DPAA2_PMD_ERR("Serdes register map failed\n");
592 if (serdes_id == LSX_SERDES_1)
593 lan_id = LSX_SERDES_LAN_NB - lan_id - 1;
595 reg = &serdes_base->lane[lan_id].lnatcsr0;
597 data = rte_read32(reg);
599 rte_write32(data | LSX_LB_EN_BIT, reg);
601 rte_write32(data & (~LSX_LB_EN_BIT), reg);
606 /* Configure dpaa2 port as recycle port */
608 dpaa2_dev_recycle_config(struct rte_eth_dev *eth_dev)
610 struct rte_device *dev = eth_dev->device;
611 struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
612 struct rte_dpaa2_device *dpaa2_dev =
613 container_of(dev, struct rte_dpaa2_device, device);
614 struct fsl_mc_io *dpni_dev = eth_dev->process_private;
615 struct dpni_port_cfg port_cfg;
618 if (priv->flags & DPAA2_TX_LOOPBACK_MODE) {
619 DPAA2_PMD_INFO("%s has been configured recycle device.",
620 eth_dev->data->name);
625 if (dpaa2_dev->ep_dev_type == DPAA2_MAC) {
626 /** For dpmac-dpni connection,
627 * try setting serdes loopback as recycle device at first.
629 if (dpaa2_svr_family == SVR_LS2088A) {
630 ret = ls_serdes_eth_lpbk(dpaa2_dev->ep_object_id, 1);
632 priv->flags |= DPAA2_TX_SERDES_LOOPBACK_MODE;
635 } else if (dpaa2_svr_family == SVR_LX2160A) {
636 ret = lx_serdes_eth_lpbk(dpaa2_dev->ep_object_id, 1);
638 priv->flags |= DPAA2_TX_SERDES_LOOPBACK_MODE;
642 DPAA2_PMD_DEBUG("Serdes loopback not support SoC(0x%08x)",
646 /** If serdes loopback is not supported for this mac,
647 * trying set mac loopback.
650 port_cfg.loopback_en = 1;
651 ret = dpni_set_port_cfg(dpni_dev, CMD_PRI_LOW,
653 DPNI_PORT_CFG_LOOPBACK,
656 DPAA2_PMD_ERR("Error(%d) to enable loopback", ret);
660 priv->flags |= DPAA2_TX_MAC_LOOPBACK_MODE;
665 if (dpaa2_dev->ep_dev_type == DPAA2_ETH &&
666 dpaa2_dev->object_id == dpaa2_dev->ep_object_id) {
667 priv->flags |= DPAA2_TX_DPNI_LOOPBACK_MODE;
676 dpaa2_dev_recycle_deconfig(struct rte_eth_dev *eth_dev)
678 struct rte_device *dev = eth_dev->device;
679 struct dpaa2_dev_priv *priv = eth_dev->data->dev_private;
680 struct rte_dpaa2_device *dpaa2_dev =
681 container_of(dev, struct rte_dpaa2_device, device);
682 struct fsl_mc_io *dpni_dev = eth_dev->process_private;
683 struct dpni_port_cfg port_cfg;
686 if (!(priv->flags & DPAA2_TX_LOOPBACK_MODE))
689 if (priv->flags & DPAA2_TX_SERDES_LOOPBACK_MODE) {
690 if (dpaa2_svr_family == SVR_LS2088A) {
691 ret = ls_serdes_eth_lpbk(dpaa2_dev->ep_object_id, 0);
693 DPAA2_PMD_WARN("Error(%d) to disable Serdes loopback",
696 priv->flags &= ~DPAA2_TX_SERDES_LOOPBACK_MODE;
698 } else if (dpaa2_svr_family == SVR_LX2160A) {
699 ret = lx_serdes_eth_lpbk(dpaa2_dev->ep_object_id, 0);
701 DPAA2_PMD_WARN("Error(%d) to disable Serdes loopback",
704 priv->flags &= ~DPAA2_TX_SERDES_LOOPBACK_MODE;
707 DPAA2_PMD_DEBUG("Serdes loopback not support SoC(0x%08x)",
712 if (priv->flags & DPAA2_TX_MAC_LOOPBACK_MODE) {
713 port_cfg.loopback_en = 0;
714 ret = dpni_set_port_cfg(dpni_dev, CMD_PRI_LOW,
716 DPNI_PORT_CFG_LOOPBACK,
719 DPAA2_PMD_ERR("Error(%d) to disable TX mac loopback",
722 priv->flags &= ~DPAA2_TX_MAC_LOOPBACK_MODE;
726 if (priv->flags & DPAA2_TX_DPNI_LOOPBACK_MODE)
727 priv->flags &= ~DPAA2_TX_DPNI_LOOPBACK_MODE;
733 dpaa2_dev_recycle_qp_setup(struct rte_dpaa2_device *dpaa2_dev,
734 uint16_t qidx, uint64_t cntx,
735 eth_rx_burst_t tx_lpbk, eth_tx_burst_t rx_lpbk,
736 struct dpaa2_queue **txq,
737 struct dpaa2_queue **rxq)
739 struct rte_eth_dev *dev;
740 struct rte_eth_dev_data *data;
741 struct dpaa2_queue *txq_tmp;
742 struct dpaa2_queue *rxq_tmp;
743 struct dpaa2_dev_priv *priv;
745 dev = dpaa2_dev->eth_dev;
747 priv = data->dev_private;
749 if (!(priv->flags & DPAA2_TX_LOOPBACK_MODE) &&
750 (tx_lpbk || rx_lpbk)) {
751 DPAA2_PMD_ERR("%s is NOT recycle device!", data->name);
756 if (qidx >= data->nb_rx_queues || qidx >= data->nb_tx_queues)
759 rte_spinlock_lock(&priv->lpbk_qp_lock);
762 dev->tx_pkt_burst = tx_lpbk;
765 dev->rx_pkt_burst = rx_lpbk;
767 txq_tmp = data->tx_queues[qidx];
768 txq_tmp->lpbk_cntx = cntx;
769 rxq_tmp = data->rx_queues[qidx];
770 rxq_tmp->lpbk_cntx = cntx;
777 rte_spinlock_unlock(&priv->lpbk_qp_lock);