xref: /openbmc/u-boot/cmd/aspeed/nettest/mactest.c (revision d82a9689b6a3d8e7d1058971a7057844ca07fe4a)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) ASPEED Technology Inc.
4  */
5 
6 #define MACTEST_C
7 
8 #include "swfunc.h"
9 #include "comminf.h"
10 #include <command.h>
11 #include <common.h>
12 #include <malloc.h>
13 #include <net.h>
14 #include <post.h>
15 #include "mem_io.h"
16 
17 #include "phy_api.h"
18 #include "mac_api.h"
19 
20 #define ARGV_MAC_IDX		1
21 #define ARGV_MDIO_IDX		2
22 #define ARGV_SPEED		3
23 #define ARGV_CTRL		4
24 #define ARGV_LOOP		5
25 #define ARGV_TEST_MODE		6
26 #define ARGV_PHY_ADDR		7
27 #define ARGV_TIMING_MARGIN	8
28 
29 
30 uint8_t __attribute__ ((aligned (1024*1024))) tdes_buf[TDES_SIZE];
31 uint8_t __attribute__ ((aligned (1024*1024))) rdes_buf[RDES_SIZE];
32 uint8_t __attribute__ ((aligned (1024*1024))) dma_buf[DMA_BUF_SIZE];
33 
34 struct mac_ctrl_desc {
35 	uint32_t base_reset_assert;
36 	uint32_t bit_reset_assert;
37 	uint32_t base_reset_deassert;
38 	uint32_t bit_reset_deassert;
39 
40 	uint32_t base_clk_stop;
41 	uint32_t bit_clk_stop;
42 	uint32_t base_clk_start;
43 	uint32_t bit_clk_start;
44 };
45 
46 static const uint32_t timeout_th_tbl[3] = {
47     TIME_OUT_Des_1G, TIME_OUT_Des_100M, TIME_OUT_Des_10M};
48 #if defined(CONFIG_ASPEED_AST2600)
49 const uint32_t mac_base_lookup_tbl[4] = {MAC1_BASE, MAC2_BASE, MAC3_BASE,
50 					 MAC4_BASE};
51 const uint32_t mdio_base_lookup_tbl[4] = {MDIO0_BASE, MDIO1_BASE, MDIO2_BASE,
52 					 MDIO3_BASE};
53 const struct mac_ctrl_desc mac_ctrl_lookup_tbl[4] = {
54 	{
55 		.base_reset_assert = 0x40, .bit_reset_assert = BIT(11),
56 		.base_reset_deassert = 0x44,.bit_reset_deassert = BIT(11),
57 		.base_clk_stop = 0x80, .bit_clk_stop = BIT(20),
58 		.base_clk_start = 0x84, .bit_clk_start = BIT(20),
59 	},
60 	{
61 		.base_reset_assert = 0x40, .bit_reset_assert = BIT(12),
62 		.base_reset_deassert = 0x44,.bit_reset_deassert = BIT(12),
63 		.base_clk_stop = 0x80, .bit_clk_stop = BIT(21),
64 		.base_clk_start = 0x84,.bit_clk_start = BIT(21),
65 	},
66 	{
67 		.base_reset_assert = 0x50, .bit_reset_assert = BIT(20),
68 		.base_reset_deassert = 0x54,.bit_reset_deassert = BIT(20),
69 		.base_clk_stop = 0x90, .bit_clk_stop = BIT(20),
70 		.base_clk_start = 0x94, .bit_clk_start = BIT(20),
71 	},
72 	{
73 		.base_reset_assert = 0x50, .bit_reset_assert = BIT(21),
74 		.base_reset_deassert = 0x54,.bit_reset_deassert = BIT(21),
75 		.base_clk_stop = 0x90, .bit_clk_stop = BIT(21),
76 		.base_clk_start = 0x94,.bit_clk_start = BIT(21),
77 	}
78 };
79 #else
80 const uint32_t mac_base_lookup_tbl[2] = {MAC1_BASE, MAC2_BASE};
81 const uint32_t mdio_base_lookup_tbl[2] = {MDIO0_BASE, MDIO1_BASE};
82 const struct mac_ctrl_desc mac_ctrl_lookup_tbl[2] = {
83 	{
84 		.base_reset_assert = 0x04, .bit_reset_assert = BIT(11),
85 		.base_reset_deassert = 0x04, .bit_reset_deassert = BIT(11),
86 		.base_clk_stop = 0x0c, .bit_clk_stop = BIT(20),
87 		.base_clk_start = 0x0c, .bit_clk_start = BIT(20),
88 	},
89 	{
90 		.base_reset_assert = 0x04, .bit_reset_assert = BIT(12),
91 		.base_reset_deassert = 0x04, .bit_reset_deassert = BIT(12),
92 		.base_clk_stop = 0x0c, .bit_clk_stop = BIT(21),
93 		.base_clk_start = 0x0c, .bit_clk_start = BIT(21),
94 	}
95 };
96 #endif
97 
98 void Print_Header(MAC_ENGINE *p_eng, uint8_t option)
99 {
100 	if (p_eng->run.speed_sel[0]) {
101 		PRINTF(option, " 1G   ");
102 	} else if (p_eng->run.speed_sel[1]) {
103 		PRINTF(option, " 100M ");
104 	} else {
105 		PRINTF(option, " 10M  ");
106 	}
107 
108 	switch (p_eng->arg.test_mode) {
109 	case 0:
110 		PRINTF(option, "TX/RX delay margin check\n");
111 		break;
112 	case 1:
113 		PRINTF(option, "TX/RX delay scan\n");
114 		break;
115 	case 2:
116 		PRINTF(option, "TX/RX delay and IO driving scan\n");
117 		break;
118 	case 3:
119 		PRINTF(option, "TX frame - ARP\n");
120 		break;
121 	case 4:
122 		PRINTF(option, "TX frame - random\n");
123 		break;
124 	case 5:
125 		PRINTF(option, "TX frame - 0x%08x\n", p_eng->arg.user_def_val);
126 		break;
127 	}
128 }
129 
130 static void print_arg_test_mode(MAC_ENGINE *p_eng)
131 {
132 	uint8_t item[32] = "test_mode[dec]";
133 
134 	if (p_eng->arg.run_mode == MODE_NCSI) {
135 		printf("%20s| 0: NCSI configuration with    "
136 		       "Disable_Channel request\n", item);
137 		printf("%20s| (default:%3d)\n", "", DEF_GTESTMODE);
138 		printf("%20s| 1: TX/RX delay scan\n", "");
139 		printf("%20s| 2: TX/RX delay and IO driving scan\n", "");
140 		printf("%20s| 3: NCSI configuration without "
141 		       "Disable_Channel request\n", "");
142 	} else {
143 		printf("%20s| (default:%3d)\n", item, DEF_GTESTMODE);
144 		printf("%20s| 0: TX/RX delay margin check\n", "");
145 		printf("%20s| 1: TX/RX delay scan\n", "");
146 		printf("%20s| 2: TX/RX delay and IO driving scan\n", "");
147 		printf("%20s| 3: TX frame - ARP\n", "");
148 		printf("%20s| 4: TX frame - random\n", "");
149 		printf("%20s| 5: TX frame - user defined (default:0x%8x)\n", "",
150 		       DEF_GUSER_DEF_PACKET_VAL);
151 	}
152 }
153 
154 static void print_arg_phy_addr(MAC_ENGINE *p_eng)
155 {
156 	uint8_t item[32] = "phy_addr[dec]";
157 
158 	printf("%20s| 0~31: PHY Address (default:%d)\n", item, DEF_GPHY_ADR);
159 }
160 
161 static void print_arg_ieee_select(MAC_ENGINE *p_eng)
162 {
163 	uint8_t item[32] = "IEEE packet select";
164 
165 	printf("%20s| 0/1/2 (default:0)  only for test_mode 3,4,5)\n", item);
166 }
167 
168 static void print_arg_delay_scan_range(MAC_ENGINE *p_eng)
169 {
170 	uint8_t item[32] = "TX/RX delay margin";
171 
172 	printf("%20s| 1/2/3/... (default:%d) only for test_mode 0\n", item,
173 	       DEF_GIOTIMINGBUND);
174 	printf("%20s| check range = (orig - margin) ~ (orig + margin)\n", "");
175 }
176 
177 static void print_arg_channel_num(MAC_ENGINE *p_eng)
178 {
179 	uint8_t item[32] = "channel_num[dec]";
180 
181 	printf("%20s| 1~32: Total Number of NCSI Channel (default:%d)\n", item,
182 	       DEF_GCHANNEL2NUM);
183 }
184 
185 static void print_arg_package_num(MAC_ENGINE *p_eng)
186 {
187 	uint8_t item[32] = "package_num[dec]";
188 
189 	printf("%20s| 1~ 8: Total Number of NCSI Package (default:%d)\n", item,
190 	       DEF_GPACKAGE2NUM);
191 }
192 
193 static void print_arg_loop(MAC_ENGINE *p_eng)
194 {
195 	uint8_t item[32] = "loop_max[dec]";
196 
197 	printf("%20s| 1G  :  (default:%3d)\n", item, DEF_GLOOP_MAX * 20);
198 	printf("%20s| 100M:  (default:%3d)\n", "", DEF_GLOOP_MAX * 2);
199 	printf("%20s| 10M :  (default:%3d)\n", "", DEF_GLOOP_MAX);
200 }
201 
202 static void print_arg_ctrl(MAC_ENGINE *p_eng)
203 {
204 	uint8_t item[32] = "ctrl[hex]";
205 
206 	printf("%20s| default  : 0x%03x\n", item, DEF_GCTRL);
207 	printf("%20s| bit0     : skip PHY init/deinit\n", "");
208 	printf("%20s| bit1     : skip PHY deinit\n", "");
209 	printf("%20s| bit2     : skip PHY ID check\n", "");
210 	printf("%20s| bit3     : reserved\n", "");
211 	printf("%20s| bit4     : PHY internal loopback\n", "");
212 	printf("%20s| bit5     : MAC internal loopback\n", "");
213 	printf("%20s| bit6     : Enable PHY RX delay\n", "");
214 	printf("%20s| bit7     : Enable PHY TX delay\n", "");
215 	printf("%20s| bit8     : RMII 50MHz Output enable\n", "");
216 	printf("%20s| bit9     : RMII REFCLK pin input enable\n", "");
217 	printf("%20s| bit10    : inverse RGMII RXCLK\n", "");
218 	printf("%20s| bit11    : reserved\n", "");
219 	printf("%20s| bit12    : TX single packet for each test point\n", "");
220 	printf("%20s| bit13    : full range scan\n", "");
221 	printf("%20s| bit15~14 : reserved\n", "");
222 	printf("%20s| bit16    : NCSI verbose log\n", "");
223 	printf("%20s| bit17    : NCSI skip RX error\n", "");
224 	printf("%20s| bit31~18 : reserved\n", "");
225 }
226 
227 static void print_arg_speed(MAC_ENGINE *p_eng)
228 {
229 	uint8_t item[32] = "speed[hex]";
230 
231 	printf("%20s| bit[0]->1G  bit[1]->100M  bit[2]->10M "
232 	       "(default:0x%02lx)\n",
233 	       item, DEF_GSPEED);
234 }
235 
236 static void print_arg_mdio_idx(MAC_ENGINE *p_eng)
237 {
238 	uint8_t item[32] = "mdio_idx[dec]";
239 
240 	printf("%20s| 0->MDIO1 1->MDIO2", item);
241 
242 	if (p_eng->env.mac_num > 2) {
243 		printf(" 2->MDIO3 3->MDIO4");
244 	}
245 	printf("\n");
246 }
247 
248 static void print_arg_mac_idx(MAC_ENGINE *p_eng)
249 {
250 	uint8_t item[32] = "mac_idx[dec]";
251 
252 	printf("%20s| 0->MAC1 1->MAC2", item);
253 
254 	if (p_eng->env.mac_num > 2) {
255 		printf(" 2->MAC3 3->MAC4");
256 	}
257 	printf("\n");
258 }
259 static void print_legend(void)
260 {
261 	printf("Legend:\n");
262 	printf("    o : OK\n");
263 	printf("    x : CRC error\n");
264 	printf("    . : packet not found\n");
265 	printf("    System default setting\n");
266 	printf("    O : OK\n");
267 	printf("    X : CRC error\n");
268 	printf("    * : packet not found\n");
269 }
270 static void print_usage(MAC_ENGINE *p_eng)
271 {
272 	if (MODE_DEDICATED == p_eng->arg.run_mode) {
273 		printf("mactest <mac_idx> <mdio_idx> <speed> <ctrl> <loop_max> <test "
274 		       "mode> <phy addr> <margin / IEEE select> <user data>\n");
275 		print_arg_mac_idx(p_eng);
276 		print_arg_mdio_idx(p_eng);
277 		print_arg_speed(p_eng);
278 		print_arg_ctrl(p_eng);
279 		print_arg_loop(p_eng);
280 		print_arg_test_mode(p_eng);
281 		print_arg_phy_addr(p_eng);
282 		print_arg_delay_scan_range(p_eng);
283 		print_arg_ieee_select(p_eng);
284 	} else if (MODE_NCSI == p_eng->arg.run_mode) {
285 		printf("ncsitest <idx> <packet num> <channel num> <test mode> "
286 		       "<margin> <ctrl>\n");
287 		print_arg_mac_idx(p_eng);
288 		print_arg_package_num(p_eng);
289 		print_arg_channel_num(p_eng);
290 		print_arg_test_mode(p_eng);
291 		print_arg_delay_scan_range(p_eng);
292 		print_arg_ctrl(p_eng);
293 	} else {
294 		printf("unknown run mode\n");
295 	}
296 }
297 
298 static void push_reg(MAC_ENGINE *p_eng)
299 {
300 	/* SCU delay settings */
301 	p_eng->io.mac12_1g_delay.value.w = readl(p_eng->io.mac12_1g_delay.addr);
302 	p_eng->io.mac12_100m_delay.value.w = readl(p_eng->io.mac12_100m_delay.addr);
303 	p_eng->io.mac12_10m_delay.value.w = readl(p_eng->io.mac12_10m_delay.addr);
304 
305 #ifdef CONFIG_ASPEED_AST2600
306 	p_eng->io.mac34_1g_delay.value.w = readl(p_eng->io.mac34_1g_delay.addr);
307 	p_eng->io.mac34_100m_delay.value.w = readl(p_eng->io.mac34_100m_delay.addr);
308 	p_eng->io.mac34_10m_delay.value.w = readl(p_eng->io.mac34_10m_delay.addr);
309 
310 	p_eng->io.mac34_drv_reg.value.w = readl(p_eng->io.mac34_drv_reg.addr);
311 #else
312 	p_eng->io.mac12_drv_reg.value.w = readl(p_eng->io.mac12_drv_reg.addr);
313 #endif
314 
315 	/* MAC registers */
316 	p_eng->reg.maccr.w = mac_reg_read(p_eng, 0x50);
317 
318 	p_eng->reg.mac_madr = mac_reg_read(p_eng, 0x08);
319 	p_eng->reg.mac_ladr = mac_reg_read(p_eng, 0x0c);
320 	p_eng->reg.mac_fear = mac_reg_read(p_eng, 0x40);
321 }
322 
323 static void pop_reg(MAC_ENGINE *p_eng)
324 {
325 	/* SCU delay settings */
326 	writel(p_eng->io.mac12_1g_delay.value.w, p_eng->io.mac12_1g_delay.addr);
327 	writel(p_eng->io.mac12_100m_delay.value.w, p_eng->io.mac12_100m_delay.addr);
328 	writel(p_eng->io.mac12_10m_delay.value.w, p_eng->io.mac12_10m_delay.addr);
329 
330 #ifdef CONFIG_ASPEED_AST2600
331 	writel(p_eng->io.mac34_1g_delay.value.w, p_eng->io.mac34_1g_delay.addr);
332 	writel(p_eng->io.mac34_100m_delay.value.w, p_eng->io.mac34_100m_delay.addr);
333 	writel(p_eng->io.mac34_10m_delay.value.w, p_eng->io.mac34_10m_delay.addr);
334 
335 	writel(p_eng->io.mac34_drv_reg.value.w, p_eng->io.mac34_drv_reg.addr);
336 #else
337 	writel(p_eng->io.mac12_drv_reg.value.w, p_eng->io.mac12_drv_reg.addr);
338 #endif
339 
340 	/* MAC registers */
341 	mac_reg_write(p_eng, 0x50, p_eng->reg.maccr.w);
342 	mac_reg_write(p_eng, 0x08, p_eng->reg.mac_madr);
343 	mac_reg_write(p_eng, 0x0c, p_eng->reg.mac_ladr);
344 	mac_reg_write(p_eng, 0x40, p_eng->reg.mac_fear);
345 }
346 
347 static void finish_close(MAC_ENGINE *p_eng)
348 {
349 	nt_log_func_name();
350 	pop_reg(p_eng);
351 }
352 
353 char finish_check(MAC_ENGINE *p_eng, int value)
354 {
355 	nt_log_func_name();
356 
357 	if (p_eng->arg.run_mode == MODE_DEDICATED) {
358 		if (p_eng->dat.FRAME_LEN)
359 			free(p_eng->dat.FRAME_LEN);
360 
361 		if (p_eng->dat.wp_lst)
362 			free(p_eng->dat.wp_lst);
363 	}
364 
365 	p_eng->flg.error = p_eng->flg.error | value;
366 
367 	if (DBG_PRINT_ERR_FLAG)
368 		printf("flags: error = %08x\n", p_eng->flg.error);
369 
370 	if (!p_eng->run.tm_tx_only)
371 		FPri_ErrFlag(p_eng, FP_LOG);
372 
373 	if (p_eng->run.TM_IOTiming)
374 		FPri_ErrFlag(p_eng, FP_IO);
375 
376 	FPri_ErrFlag(p_eng, STD_OUT);
377 
378 	if (!p_eng->run.tm_tx_only)
379 		FPri_End(p_eng, FP_LOG);
380 
381 	if (p_eng->run.TM_IOTiming)
382 		FPri_End(p_eng, FP_IO);
383 
384 	FPri_End(p_eng, STD_OUT);
385 
386 	if (!p_eng->run.tm_tx_only)
387 		FPri_RegValue(p_eng, FP_LOG);
388 	if (p_eng->run.TM_IOTiming)
389 		FPri_RegValue(p_eng, FP_IO);
390 
391 	finish_close(p_eng);
392 
393 	if (p_eng->flg.error) {
394 		return (1);
395 	} else {
396 		return (0);
397 	}
398 }
399 
400 static uint32_t check_test_mode(MAC_ENGINE *p_eng)
401 {
402 	if (p_eng->arg.run_mode == MODE_NCSI ) {
403 		switch (p_eng->arg.test_mode) {
404 		case 0:
405 			break;
406 		case 1:
407 			p_eng->run.TM_IOTiming = 1;
408 			break;
409 		case 2:
410 			p_eng->run.TM_IOTiming = 1;
411 			p_eng->run.TM_IOStrength = 1;
412 			break;
413 		case 3:
414 			p_eng->run.TM_NCSI_DiSChannel = 0;
415 			break;
416 		default:
417 			printf("Error test_mode!!!\n");
418 			print_arg_test_mode(p_eng);
419 			return (1);
420 		}
421 	} else {
422 		switch (p_eng->arg.test_mode) {
423 		case 0:
424 			break;
425 		case 1:
426 			p_eng->run.TM_IOTiming = 1;
427 			break;
428 		case 2:
429 			p_eng->run.TM_IOTiming = 1;
430 			p_eng->run.TM_IOStrength = 1;
431 			break;
432 		case 3:
433 			/* TX ARP frame */
434 			p_eng->run.TM_RxDataEn = 0;
435 			p_eng->run.tm_tx_only = 1;
436 			p_eng->run.TM_IEEE = 0;
437 			break;
438 		case 4:
439 		case 5:
440 			p_eng->run.TM_RxDataEn = 0;
441 			p_eng->run.tm_tx_only = 1;
442 			p_eng->run.TM_IEEE = 1;
443 			break;
444 		default:
445 			printf("Error test_mode!!!\n");
446 			print_arg_test_mode(p_eng);
447 			return (1);
448 		}
449 	}
450 
451 	if (0 == p_eng->run.TM_IOStrength) {
452 		p_eng->io.drv_upper_bond = 0;
453 	}
454 	return 0;
455 }
456 
457 /**
458  * @brief enable/disable MAC
459  * @param[in] p_eng - MAC_ENGINE
460  *
461  * AST2600 uses synchronous reset scheme, so the bits for reset assert and
462  * deassert are the same
463  * e.g. MAC#1: SCU04[11] = 1 --> MAC#1 reset assert
464  *                       = 0 --> MAC#1 reset de-assert
465  *
466  * AST2600 uses asynchronous reset scheme, so the bits for reset assert and
467  * deassert are different
468  * e.g. MAC#1: SCU40[11] = 1 --> MAC#1 reset assert
469  *             SCU44[11] = 1 --> MAC#1 reset de-assert
470  *
471  * The same design concept is also adopted on clock stop/start.
472  */
473 void scu_disable_mac(MAC_ENGINE *p_eng)
474 {
475 	uint32_t mac_idx = p_eng->run.mac_idx;
476 	const struct mac_ctrl_desc *p_mac = &mac_ctrl_lookup_tbl[mac_idx];
477 	uint32_t reg;
478 
479 	debug("MAC%d:reset assert=0x%02x[%08x] deassert=0x%02x[%08x]\n",
480 	      mac_idx, p_mac->base_reset_assert, p_mac->bit_reset_assert,
481 	      p_mac->base_reset_deassert, p_mac->bit_reset_deassert);
482 	debug("MAC%d:clock stop=0x%02x[%08x] start=0x%02x[%08x]\n", mac_idx,
483 	      p_mac->base_clk_stop, p_mac->bit_clk_stop, p_mac->base_clk_start,
484 	      p_mac->bit_clk_start);
485 
486 	reg = SCU_RD(p_mac->base_reset_assert);
487 	debug("reset reg: 0x%08x\n", reg);
488 	reg |= p_mac->bit_reset_assert;
489 	debug("reset reg: 0x%08x\n", reg);
490 	SCU_WR(reg, p_mac->base_reset_assert);
491 	/* issue a dummy read to ensure command is in order */
492 	reg = SCU_RD(p_mac->base_reset_assert);
493 
494 	reg = SCU_RD(p_mac->base_clk_stop);
495 	debug("clock reg: 0x%08x\n", reg);
496 	reg |= p_mac->bit_clk_stop;
497 	debug("clock reg: 0x%08x\n", reg);
498 	SCU_WR(reg, p_mac->base_clk_stop);
499 	/* issue a dummy read to ensure command is in order */
500 	reg = SCU_RD(p_mac->base_clk_stop);
501 }
502 
503 void scu_enable_mac(MAC_ENGINE *p_eng)
504 {
505 	uint32_t mac_idx = p_eng->run.mac_idx;
506 	const struct mac_ctrl_desc *p_mac = &mac_ctrl_lookup_tbl[mac_idx];
507 	uint32_t reg;
508 
509 	debug("MAC%d:reset assert=0x%02x[%08x] deassert=0x%02x[%08x]\n",
510 	      mac_idx, p_mac->base_reset_assert, p_mac->bit_reset_assert,
511 	      p_mac->base_reset_deassert, p_mac->bit_reset_deassert);
512 	debug("MAC%d:clock stop=0x%02x[%08x] start=0x%02x[%08x]\n", mac_idx,
513 	      p_mac->base_clk_stop, p_mac->bit_clk_stop, p_mac->base_clk_start,
514 	      p_mac->bit_clk_start);
515 
516 #ifdef CONFIG_ASPEED_AST2600
517 	reg = SCU_RD(p_mac->base_reset_deassert);
518 	debug("reset reg: 0x%08x\n", reg);
519 	reg |= p_mac->bit_reset_deassert;
520 	debug("reset reg: 0x%08x\n", reg);
521 	SCU_WR(reg, p_mac->base_reset_deassert);
522 	/* issue a dummy read to ensure command is in order */
523 	reg = SCU_RD(p_mac->base_reset_deassert);
524 
525 	reg = SCU_RD(p_mac->base_clk_start);
526 	debug("clock reg: 0x%08x\n", reg);
527 	reg |= p_mac->bit_clk_start;
528 	debug("clock reg: 0x%08x\n", reg);
529 	SCU_WR(reg, p_mac->base_clk_start);
530 	/* issue a dummy read to ensure command is in order */
531 	reg = SCU_RD(p_mac->base_clk_start);
532 #else
533 	reg = SCU_RD(p_mac->base_reset_assert);
534 	debug("reset reg: 0x%08x\n", reg);
535 	reg &= ~p_mac->bit_reset_assert;
536 	debug("reset reg: 0x%08x\n", reg);
537 	SCU_WR(reg, p_mac->base_reset_assert);
538 
539 	reg = SCU_RD(p_mac->base_clk_stop);
540 	debug("clock reg: 0x%08x\n", reg);
541 	reg &= ~p_mac->bit_clk_stop;
542 	debug("clock reg: 0x%08x\n", reg);
543 	SCU_WR(reg, p_mac->base_clk_stop);
544 #endif
545 }
546 
547 /**
548  * @brief setup mdc/mdio pinmix
549  * @todo push/pop pinmux registers
550 */
551 void scu_set_pinmux(MAC_ENGINE *p_eng)
552 {
553 	uint32_t reg;
554 	nt_log_func_name();
555 
556 #ifdef CONFIG_ASPEED_AST2600
557 	/* MDC/MDIO pinmux */
558 	switch (p_eng->run.mdio_idx) {
559 	case 0:
560 		reg = SCU_RD(0x430) | GENMASK(17, 16);
561 		SCU_WR(reg, 0x430);
562 		break;
563 	case 1:
564 		reg = SCU_RD(0x470) & ~GENMASK(13, 12);
565 		SCU_WR(reg, 0x470);
566 		reg = SCU_RD(0x410) | GENMASK(13, 12);
567 		SCU_WR(reg, 0x410);
568 		break;
569 	case 2:
570 		reg = SCU_RD(0x470) & ~GENMASK(1, 0);
571 		SCU_WR(reg, 0x470);
572 		reg = SCU_RD(0x410) | GENMASK(1, 0);
573 		SCU_WR(reg, 0x410);
574 		break;
575 	case 3:
576 		reg = SCU_RD(0x470) & ~GENMASK(3, 2);
577 		SCU_WR(reg, 0x470);
578 		reg = SCU_RD(0x410) | GENMASK(3, 2);
579 		SCU_WR(reg, 0x410);
580 		break;
581 	default:
582 		printf("%s:undefined MDIO idx %d\n", __func__,
583 		       p_eng->run.mdio_idx);
584 	}
585 
586 	switch (p_eng->run.mac_idx) {
587 	case 0:
588 #ifdef CONFIG_FPGA_ASPEED
589 		setbits_le32(SCU_BASE + 0x410, BIT(4));
590 #else
591 		setbits_le32(SCU_BASE + 0x400, GENMASK(11, 0));
592 		setbits_le32(SCU_BASE + 0x410, BIT(4));
593 		clrbits_le32(SCU_BASE + 0x470, BIT(4));
594 #endif
595 		break;
596 	case 1:
597 		setbits_le32(SCU_BASE + 0x400, GENMASK(23, 12));
598 		setbits_le32(SCU_BASE + 0x410, BIT(5));
599 		clrbits_le32(SCU_BASE + 0x470, BIT(5));
600 		break;
601 	case 2:
602 		setbits_le32(SCU_BASE + 0x410, GENMASK(27, 16));
603 		setbits_le32(SCU_BASE + 0x410, BIT(6));
604 		clrbits_le32(SCU_BASE + 0x470, BIT(6));
605 		break;
606 	case 3:
607 		clrbits_le32(SCU_BASE + 0x410, GENMASK(31, 28));
608 		setbits_le32(SCU_BASE + 0x4b0, GENMASK(31, 28));
609 		clrbits_le32(SCU_BASE + 0x474, GENMASK(7, 0));
610 		clrbits_le32(SCU_BASE + 0x414, GENMASK(7, 0));
611 		setbits_le32(SCU_BASE + 0x4b4, GENMASK(7, 0));
612 		setbits_le32(SCU_BASE + 0x410, BIT(7));
613 		clrbits_le32(SCU_BASE + 0x470, BIT(7));
614 		break;
615 
616 	}
617 
618 	debug("SCU410: %08x %08x %08x %08x\n", SCU_RD(0x410), SCU_RD(0x414), SCU_RD(0x418), SCU_RD(0x41c));
619 	debug("SCU430: %08x %08x %08x %08x\n", SCU_RD(0x430), SCU_RD(0x434), SCU_RD(0x438), SCU_RD(0x43c));
620 	debug("SCU470: %08x %08x %08x %08x\n", SCU_RD(0x470), SCU_RD(0x474), SCU_RD(0x478), SCU_RD(0x47c));
621 	debug("SCU4b0: %08x %08x %08x %08x\n", SCU_RD(0x4b0), SCU_RD(0x4b4), SCU_RD(0x4b8), SCU_RD(0x4bc));
622 #else
623 	/* MDC/MDIO pinmux */
624 	if (p_eng->run.mdio_idx == 0) {
625 		setbits_le32(SCU_BASE + 88, GENMASK(31, 30));
626 	} else {
627 		clrsetbits_le32(SCU_BASE + 90, BIT(6), BIT(2));
628 	}
629 
630 	/* enable MAC#nLINK pin */
631 	setbits_le32(SCU_BASE + 80, BIT(p_eng->run.mac_idx));
632 #endif
633 }
634 
635 static uint32_t check_mac_idx(MAC_ENGINE *p_eng)
636 {
637 	/* check if legal run_idx */
638 	if (p_eng->arg.mac_idx > p_eng->env.mac_num - 1) {
639 		printf("invalid run_idx = %d\n", p_eng->arg.mac_idx);
640 		return 1;
641 	}
642 
643 	return 0;
644 }
645 
646 static void calc_loop_check_num(MAC_ENGINE *p_eng)
647 {
648 	nt_log_func_name();
649 
650 	if (p_eng->run.IO_MrgChk ||
651 	    (p_eng->arg.run_speed == SET_1G_100M_10MBPS) ||
652 	    (p_eng->arg.run_speed == SET_100M_10MBPS)) {
653 		p_eng->run.LOOP_CheckNum = p_eng->run.loop_max;
654 	} else {
655 		switch (p_eng->arg.run_speed) {
656 		case SET_1GBPS:
657 			p_eng->run.CheckBuf_MBSize = MOVE_DATA_MB_SEC;
658 			break;
659 		case SET_100MBPS:
660 			p_eng->run.CheckBuf_MBSize = (MOVE_DATA_MB_SEC >> 3);
661 			break;
662 		case SET_10MBPS:
663 			p_eng->run.CheckBuf_MBSize = (MOVE_DATA_MB_SEC >> 6);
664 			break;
665 		}
666 		p_eng->run.LOOP_CheckNum =
667 		    (p_eng->run.CheckBuf_MBSize /
668 		     (((p_eng->dat.Des_Num * DMA_PakSize) >> 20) + 1));
669 	}
670 }
671 static uint32_t setup_interface(MAC_ENGINE *p_eng);
672 static uint32_t setup_running(MAC_ENGINE *p_eng)
673 {
674 	uint32_t n_desp_min;
675 	int i;
676 
677 	if (0 != check_mac_idx(p_eng)) {
678 		return 1;
679 	}
680 	p_eng->run.mac_idx = p_eng->arg.mac_idx;
681 	p_eng->run.mac_base = mac_base_lookup_tbl[p_eng->run.mac_idx];
682 
683 	p_eng->run.mdio_idx = p_eng->arg.mdio_idx;
684 	p_eng->run.mdio_base = mdio_base_lookup_tbl[p_eng->run.mdio_idx];
685 
686 	p_eng->run.is_rgmii = p_eng->env.is_1g_valid[p_eng->run.mac_idx];
687 
688 	if (p_eng->arg.run_mode == MODE_NCSI) {
689 #ifdef CONFIG_ASPEED_AST2600
690 		/**
691 		 * NCSI needs for 3.3V IO voltage but MAC#1 & MAC#2 only
692 		 * support 1.8V. So NCSI can only runs on MAC#3 or MAC#4
693 		 */
694 		if (p_eng->run.mac_idx < 2) {
695 			printf("\nNCSI must runs on MAC#3 or MAC#4\n");
696 			return 1;
697 		}
698 
699 		if (p_eng->run.is_rgmii) {
700 			hw_strap2_t strap2;
701 
702 			printf("\nNCSI must be RMII interface, force the strap value:\n");
703 			printf("\nbefore: SCU510=%08x\n", SCU_RD(0x510));
704 			strap2.w = 0;
705 			if (p_eng->run.mac_idx == 2) {
706 				strap2.b.mac3_interface = 1;
707 			} else if (p_eng->run.mac_idx == 3) {
708 				strap2.b.mac4_interface = 1;
709 			}
710 			SCU_WR(strap2.w, 0x514);
711 			while (SCU_RD(0x510) & strap2.w);
712 			printf("\nafter: SCU510=%08x\n", SCU_RD(0x510));
713 			/* update interface setting */
714 			setup_interface(p_eng);
715 			p_eng->run.is_rgmii = p_eng->env.is_1g_valid[p_eng->run.mac_idx];
716 		}
717 #else
718 		if (p_eng->run.is_rgmii) {
719 			printf("\nNCSI must be RMII interface\n");
720 			return 1;
721 		}
722 #endif
723 	}
724 
725 	for (i = 0; i < 3; i++) {
726 		if (p_eng->arg.run_speed & (1 << i))
727 			p_eng->run.speed_cfg[i] = 1;
728 	}
729 
730 	if (p_eng->arg.run_mode == MODE_NCSI) {
731 		/*
732 		 * [Arg]check GPackageTolNum
733 		 * [Arg]check GChannelTolNum
734 		 */
735 		if ((p_eng->arg.GPackageTolNum < 1) ||
736 		    (p_eng->arg.GPackageTolNum > 8)) {
737 			print_arg_package_num(p_eng);
738 			return (1);
739 		}
740 		if ((p_eng->arg.GChannelTolNum < 1) ||
741 		    (p_eng->arg.GChannelTolNum > 32)) {
742 			print_arg_channel_num(p_eng);
743 			return (1);
744 		}
745 	} else {
746 		/* [Arg]check ctrl */
747 		if (p_eng->arg.ctrl.w & 0xfffc0000) {
748 			print_arg_ctrl(p_eng);
749 			return (1);
750 		}
751 
752 		if (p_eng->arg.phy_addr > 31) {
753 			printf("Error phy_adr!!!\n");
754 			print_arg_phy_addr(p_eng);
755 			return (1);
756 		}
757 
758 		if (0 == p_eng->arg.loop_max) {
759 			switch (p_eng->arg.run_speed) {
760 			case SET_1GBPS:
761 				p_eng->arg.loop_max = DEF_GLOOP_MAX * 20;
762 				break;
763 			case SET_100MBPS:
764 				p_eng->arg.loop_max = DEF_GLOOP_MAX * 2;
765 				break;
766 			case SET_10MBPS:
767 				p_eng->arg.loop_max = DEF_GLOOP_MAX;
768 				break;
769 			case SET_1G_100M_10MBPS:
770 				p_eng->arg.loop_max = DEF_GLOOP_MAX * 20;
771 				break;
772 			case SET_100M_10MBPS:
773 				p_eng->arg.loop_max = DEF_GLOOP_MAX * 2;
774 				break;
775 			}
776 		}
777 	}
778 
779 	if (0 != check_test_mode(p_eng)) {
780 		return 1;
781 	}
782 
783 	if (p_eng->run.tm_tx_only) {
784 		p_eng->run.ieee_sel = p_eng->arg.ieee_sel;
785 		p_eng->run.delay_margin = 0;
786 	} else {
787 		p_eng->run.ieee_sel = 0;
788 		p_eng->run.delay_margin = p_eng->arg.delay_scan_range;
789 #if 0
790 		if (p_eng->run.delay_margin == 0) {
791 			printf("Error IO margin!!!\n");
792 			print_arg_delay_scan_range(p_eng);
793 			return(1);
794 		}
795 #endif
796 	}
797 
798 	if (!p_eng->env.is_1g_valid[p_eng->run.mac_idx])
799 		p_eng->run.speed_cfg[ 0 ] = 0;
800 
801 	p_eng->run.tdes_base = (uint32_t)(&tdes_buf[0]);
802 	p_eng->run.rdes_base = (uint32_t)(&rdes_buf[0]);
803 
804 	if (p_eng->run.TM_IOTiming || p_eng->run.delay_margin)
805 		p_eng->run.IO_MrgChk = 1;
806 	else
807 		p_eng->run.IO_MrgChk = 0;
808 
809 	p_eng->phy.Adr         = p_eng->arg.phy_addr;
810 	p_eng->phy.loopback    = p_eng->arg.ctrl.b.phy_int_loopback;
811 	p_eng->phy.default_phy = p_eng->run.TM_DefaultPHY;
812 
813 	p_eng->run.loop_max = p_eng->arg.loop_max;
814 	calc_loop_check_num(p_eng);
815 
816 	//------------------------------------------------------------
817 	// Descriptor Number
818 	//------------------------------------------------------------
819 	//------------------------------
820 	// [Dat]setup Des_Num
821 	// [Dat]setup DMABuf_Size
822 	// [Dat]setup DMABuf_Num
823 	//------------------------------
824 	if (p_eng->arg.run_mode == MODE_DEDICATED) {
825 		n_desp_min = p_eng->run.TM_IOTiming;
826 
827 		if (p_eng->arg.ctrl.b.skip_phy_id_check &&
828 		    (p_eng->arg.test_mode == 0))
829 			/* for SMSC's LAN9303 issue */
830 			p_eng->dat.Des_Num = 114;
831 		else {
832 			switch (p_eng->arg.run_speed) {
833 			case SET_1GBPS:
834 				p_eng->dat.Des_Num =
835 				    p_eng->run.delay_margin
836 					? 100
837 					: (n_desp_min) ? 512 : 4096;
838 				break;
839 			case SET_100MBPS:
840 				p_eng->dat.Des_Num =
841 				    p_eng->run.delay_margin
842 					? 100
843 					: (n_desp_min) ? 512 : 4096;
844 				break;
845 			case SET_10MBPS:
846 				p_eng->dat.Des_Num =
847 				    p_eng->run.delay_margin
848 					? 100
849 					: (n_desp_min) ? 100 : 830;
850 				break;
851 			case SET_1G_100M_10MBPS:
852 				p_eng->dat.Des_Num =
853 				    p_eng->run.delay_margin
854 					? 100
855 					: (n_desp_min) ? 100 : 830;
856 				break;
857 			case SET_100M_10MBPS:
858 				p_eng->dat.Des_Num =
859 				    p_eng->run.delay_margin
860 					? 100
861 					: (n_desp_min) ? 100 : 830;
862 				break;
863 			}
864 		}
865 
866 		if (p_eng->arg.ctrl.b.single_packet)
867 			p_eng->dat.Des_Num = 1;
868 
869 		/* keep in order: Des_Num -> DMABuf_Size -> DMABuf_Num */
870 		p_eng->dat.Des_Num_Org = p_eng->dat.Des_Num;
871 		p_eng->dat.DMABuf_Size = DMA_BufSize;
872 		p_eng->dat.DMABuf_Num = DMA_BufNum;
873 
874 		if (DbgPrn_Info) {
875 			printf("CheckBuf_MBSize : %d\n",
876 			       p_eng->run.CheckBuf_MBSize);
877 			printf("LOOP_CheckNum   : %d\n",
878 			       p_eng->run.LOOP_CheckNum);
879 			printf("Des_Num         : %d\n", p_eng->dat.Des_Num);
880 			printf("DMA_BufSize     : %d bytes\n",
881 			       p_eng->dat.DMABuf_Size);
882 			printf("DMA_BufNum      : %d\n", p_eng->dat.DMABuf_Num);
883 			printf("DMA_PakSize     : %d\n", DMA_PakSize);
884 			printf("\n");
885 		}
886 		if (2 > p_eng->dat.DMABuf_Num)
887 			return (finish_check(p_eng, Err_Flag_DMABufNum));
888 	}
889 
890 	return 0;
891 }
892 
893 /**
894  * @brief setup environment according to HW strap registers
895 */
896 static uint32_t setup_interface(MAC_ENGINE *p_eng)
897 {
898 #ifdef CONFIG_ASPEED_AST2600
899 	hw_strap1_t strap1;
900 	hw_strap2_t strap2;
901 
902 	strap1.w = SCU_RD(0x500);
903 	strap2.w = SCU_RD(0x510);
904 
905 	p_eng->env.is_1g_valid[0] = strap1.b.mac1_interface;
906 	p_eng->env.is_1g_valid[1] = strap1.b.mac2_interface;
907 	p_eng->env.is_1g_valid[2] = strap2.b.mac3_interface;
908 	p_eng->env.is_1g_valid[3] = strap2.b.mac4_interface;
909 
910 	p_eng->env.at_least_1g_valid =
911 	    p_eng->env.is_1g_valid[0] | p_eng->env.is_1g_valid[1] |
912 	    p_eng->env.is_1g_valid[2] | p_eng->env.is_1g_valid[3];
913 #else
914 	hw_strap1_t strap1;
915 	strap1.w = SCU_RD(0x70);
916 	p_eng->env.is_1g_valid[0] = strap1.b.mac1_interface;
917 	p_eng->env.is_1g_valid[1] = strap1.b.mac2_interface;
918 
919 	p_eng->env.at_least_1g_valid =
920 	    p_eng->env.is_1g_valid[0] | p_eng->env.is_1g_valid[1];
921 #endif
922 	return 0;
923 }
924 
925 /**
926  * @brief setup chip compatibility accoriding to the chip ID register
927 */
928 static uint32_t setup_chip_compatibility(MAC_ENGINE *p_eng)
929 {
930 	uint32_t reg_addr;
931 	uint32_t id, version;
932 	uint32_t is_valid;
933 
934 	p_eng->env.ast2600 = 0;
935 	p_eng->env.ast2500 = 0;
936 
937 #if defined(CONFIG_ASPEED_AST2600)
938 	reg_addr = 0x04;
939 #else
940 	reg_addr = 0x7c;
941 #endif
942 	is_valid = 0;
943 	id = (SCU_RD(reg_addr) & GENMASK(31, 24)) >> 24;
944 	version = (SCU_RD(reg_addr) & GENMASK(23, 16)) >> 16;
945 
946 #if defined(CONFIG_FPGA_ASPEED) && defined(CONFIG_ASPEED_AST2600)
947 	id = 0x5;
948 #endif
949 	if (id == 0x5) {
950 		printf("chip: AST2600 A%d\n", version);
951 		p_eng->env.ast2600 = 1;
952 		p_eng->env.ast2500 = 1;
953 		p_eng->env.mac_num = 4;
954 		p_eng->env.is_new_mdio_reg[0] = 1;
955 		p_eng->env.is_new_mdio_reg[1] = 1;
956 		p_eng->env.is_new_mdio_reg[2] = 1;
957 		p_eng->env.is_new_mdio_reg[3] = 1;
958 		is_valid = 1;
959 	} else if (id == 0x4) {
960 		printf("chip: AST2500 A%d\n", version);
961 		p_eng->env.ast2500 = 1;
962 		p_eng->env.mac_num = 2;
963 		p_eng->env.is_new_mdio_reg[0] = MAC1_RD(0x40) >> 31;
964 		p_eng->env.is_new_mdio_reg[1] = MAC2_RD(0x40) >> 31;
965 		is_valid = 1;
966 	}
967 
968 	if (0 == is_valid) {
969 		printf("unknown chip\n");
970 		return 1;
971 	}
972 
973 	return 0;
974 }
975 
976 /**
977  * @brief setup environment accoriding to the HW strap and chip ID
978 */
979 static uint32_t setup_env(MAC_ENGINE *p_eng)
980 {
981 	if (0 != setup_chip_compatibility(p_eng)) {
982 		return 1;
983 	}
984 
985 	setup_interface(p_eng);
986 	return 0;
987 }
988 
989 static uint32_t init_mac_engine(MAC_ENGINE *p_eng, uint32_t mode)
990 {
991 	memset(p_eng, 0, sizeof(MAC_ENGINE));
992 
993 	if (0 != setup_env(p_eng)) {
994 		return 1;
995 	}
996 
997 	p_eng->arg.run_mode = mode;
998 	p_eng->arg.delay_scan_range = DEF_GIOTIMINGBUND;
999 	p_eng->arg.test_mode = DEF_GTESTMODE;
1000 
1001 	if (p_eng->arg.run_mode == MODE_NCSI ) {
1002 		p_eng->arg.GARPNumCnt = DEF_GARPNUMCNT;
1003 		p_eng->arg.GChannelTolNum = DEF_GCHANNEL2NUM;
1004 		p_eng->arg.GPackageTolNum = DEF_GPACKAGE2NUM;
1005 		p_eng->arg.ctrl.w = 0;
1006 		p_eng->arg.run_speed = SET_100MBPS;        // In NCSI mode, we set to 100M bps
1007 	} else {
1008 		p_eng->arg.user_def_val  = DEF_GUSER_DEF_PACKET_VAL;
1009 		p_eng->arg.phy_addr  = DEF_GPHY_ADR;
1010 		p_eng->arg.loop_inf = 0;
1011 		p_eng->arg.loop_max = 0;
1012 		p_eng->arg.ctrl.w = DEF_GCTRL;
1013 		p_eng->arg.run_speed = DEF_GSPEED;
1014 	}
1015 
1016 	p_eng->flg.print_en  = 1;
1017 
1018 	p_eng->run.TM_TxDataEn = 1;
1019 	p_eng->run.TM_RxDataEn = 1;
1020 	p_eng->run.TM_NCSI_DiSChannel = 1;
1021 
1022 	/* setup
1023 	 * 1. delay control register
1024 	 * 2. driving strength control register and upper/lower bond
1025 	 * 3. MAC control register
1026 	 */
1027 #ifdef CONFIG_ASPEED_AST2600
1028 	p_eng->io.mac12_1g_delay.addr = SCU_BASE + 0x340;
1029 	p_eng->io.mac12_1g_delay.tx_min = 0;
1030 	p_eng->io.mac12_1g_delay.tx_max = 63;
1031 	p_eng->io.mac12_1g_delay.rx_min = -63;
1032 	p_eng->io.mac12_1g_delay.rx_max = 63;
1033 	p_eng->io.mac12_1g_delay.rmii_tx_min = 0;
1034 	p_eng->io.mac12_1g_delay.rmii_tx_max = 1;
1035 	p_eng->io.mac12_1g_delay.rmii_rx_min = 0;
1036 	p_eng->io.mac12_1g_delay.rmii_rx_max = 63;
1037 
1038 	p_eng->io.mac12_100m_delay.addr = SCU_BASE + 0x348;
1039 	p_eng->io.mac12_100m_delay.tx_min = 0;
1040 	p_eng->io.mac12_100m_delay.tx_max = 63;
1041 	p_eng->io.mac12_100m_delay.rx_min = -63;
1042 	p_eng->io.mac12_100m_delay.rx_max = 63;
1043 	p_eng->io.mac12_10m_delay.addr = SCU_BASE + 0x34c;
1044 	p_eng->io.mac12_10m_delay.tx_min = 0;
1045 	p_eng->io.mac12_10m_delay.tx_max = 63;
1046 	p_eng->io.mac12_10m_delay.rx_min = -63;
1047 	p_eng->io.mac12_10m_delay.rx_max = 63;
1048 
1049 	p_eng->io.mac34_1g_delay.addr = SCU_BASE + 0x350;
1050 	p_eng->io.mac34_1g_delay.tx_min = 0;
1051 	p_eng->io.mac34_1g_delay.tx_max = 63;
1052 	p_eng->io.mac34_1g_delay.rx_min = -63;
1053 	p_eng->io.mac34_1g_delay.rx_max = 63;
1054 	p_eng->io.mac34_1g_delay.rmii_tx_min = 0;
1055 	p_eng->io.mac34_1g_delay.rmii_tx_max = 1;
1056 	p_eng->io.mac34_1g_delay.rmii_rx_min = 0;
1057 	p_eng->io.mac34_1g_delay.rmii_rx_max = 63;
1058 	p_eng->io.mac34_100m_delay.addr = SCU_BASE + 0x358;
1059 	p_eng->io.mac34_100m_delay.tx_min = 0;
1060 	p_eng->io.mac34_100m_delay.tx_max = 63;
1061 	p_eng->io.mac34_100m_delay.rx_min = -63;
1062 	p_eng->io.mac34_100m_delay.rx_max = 63;
1063 	p_eng->io.mac34_10m_delay.addr = SCU_BASE + 0x35c;
1064 	p_eng->io.mac34_10m_delay.tx_min = 0;
1065 	p_eng->io.mac34_10m_delay.tx_max = 63;
1066 	p_eng->io.mac34_10m_delay.rx_min = -63;
1067 	p_eng->io.mac34_10m_delay.rx_max = 63;
1068 
1069 	p_eng->io.mac34_drv_reg.addr = SCU_BASE + 0x458;
1070 	p_eng->io.mac34_drv_reg.drv_max = 0x3;
1071 	p_eng->io.drv_upper_bond = 0x3;
1072 	p_eng->io.drv_lower_bond = 0;
1073 #else
1074 	p_eng->io.mac12_1g_delay.addr = SCU_BASE + 0x48;
1075 	p_eng->io.mac12_1g_delay.tx_min = 0;
1076 	p_eng->io.mac12_1g_delay.tx_max = 63;
1077 	p_eng->io.mac12_1g_delay.rx_min = 0;
1078 	p_eng->io.mac12_1g_delay.rx_max = 63;
1079 	p_eng->io.mac12_1g_delay.rmii_tx_min = 0;
1080 	p_eng->io.mac12_1g_delay.rmii_tx_max = 1;
1081 	p_eng->io.mac12_1g_delay.rmii_rx_min = 0;
1082 	p_eng->io.mac12_1g_delay.rmii_rx_max = 63;
1083 	p_eng->io.mac12_100m_delay.addr = SCU_BASE + 0xb8;
1084 	p_eng->io.mac12_100m_delay.tx_min = 0;
1085 	p_eng->io.mac12_100m_delay.tx_max = 63;
1086 	p_eng->io.mac12_100m_delay.rx_min = 0;
1087 	p_eng->io.mac12_100m_delay.rx_max = 63;
1088 	p_eng->io.mac12_10m_delay.addr = SCU_BASE + 0xbc;
1089 	p_eng->io.mac12_10m_delay.tx_min = 0;
1090 	p_eng->io.mac12_10m_delay.tx_max = 63;
1091 	p_eng->io.mac12_10m_delay.rx_min = 0;
1092 	p_eng->io.mac12_10m_delay.rx_max = 63;
1093 
1094 	p_eng->io.mac34_1g_delay.addr = 0;
1095 	p_eng->io.mac34_100m_delay.addr = 0;
1096 	p_eng->io.mac34_10m_delay.addr = 0;
1097 
1098 	p_eng->io.mac12_drv_reg.addr = SCU_BASE + 0x90;
1099 	p_eng->io.mac12_drv_reg.drv_max = 0x1;
1100 	p_eng->io.drv_upper_bond = 0x1;
1101 	p_eng->io.drv_lower_bond = 0;
1102 #endif
1103 	return 0;
1104 }
1105 
1106 static uint32_t parse_arg_dedicated(int argc, char *const argv[],
1107 				    MAC_ENGINE *p_eng)
1108 {
1109 	switch (argc) {
1110 	case 10:
1111 		p_eng->arg.user_def_val = simple_strtol(argv[9], NULL, 16);
1112 	case 9:
1113 		p_eng->arg.delay_scan_range = simple_strtol(argv[8], NULL, 10);
1114 		p_eng->arg.ieee_sel = p_eng->arg.delay_scan_range;
1115 	case 8:
1116 		p_eng->arg.phy_addr = simple_strtol(argv[7], NULL, 10);
1117 	case 7:
1118 		p_eng->arg.test_mode = simple_strtol(argv[6], NULL, 16);
1119 		printf("test mode = %d\n", p_eng->arg.test_mode);
1120 	case 6:
1121 		p_eng->arg.loop_max = simple_strtol(argv[5], NULL, 10);
1122 		if (p_eng->arg.loop_max == -1) {
1123 			p_eng->arg.loop_inf = 1;
1124 		}
1125 		printf("loop max=%d, loop_inf=%d\n", p_eng->arg.loop_max, p_eng->arg.loop_inf);
1126 	case 5:
1127 		p_eng->arg.ctrl.w = simple_strtol(argv[4], NULL, 16);
1128 		printf("ctrl=0x%05x\n", p_eng->arg.ctrl.w);
1129 	case 4:
1130 		p_eng->arg.run_speed = simple_strtol(argv[3], NULL, 16);
1131 		printf("speed=0x%1x\n", p_eng->arg.run_speed);
1132 	case 3:
1133 		p_eng->arg.mdio_idx = simple_strtol(argv[2], NULL, 10);
1134 		printf("mdio_idx=%d\n", p_eng->arg.mdio_idx);
1135 	}
1136 
1137 	return 0;
1138 }
1139 
1140 static uint32_t parse_arg_ncsi(int argc, char *const argv[], MAC_ENGINE *p_eng)
1141 {
1142 	switch (argc) {
1143 	case 8:
1144 		p_eng->arg.GARPNumCnt = simple_strtol(argv[7], NULL, 10);
1145 	case 7:
1146 		p_eng->arg.ctrl.w = simple_strtol(argv[6], NULL, 16);
1147 	case 6:
1148 		p_eng->arg.delay_scan_range = simple_strtol(argv[5], NULL, 10);
1149 	case 5:
1150 		p_eng->arg.test_mode = simple_strtol(argv[4], NULL, 16);
1151 	case 4:
1152 		p_eng->arg.GChannelTolNum  = simple_strtol(argv[3], NULL, 10);
1153 	case 3:
1154 		p_eng->arg.GPackageTolNum  = simple_strtol(argv[2], NULL, 10);
1155 	}
1156 	return 0;
1157 }
1158 
1159 
1160 static void disable_wdt(MAC_ENGINE *p_eng)
1161 {
1162 	/* FIXME */
1163 	return;
1164 }
1165 
1166 static uint32_t setup_data(MAC_ENGINE *p_eng)
1167 {
1168 	if (p_eng->arg.run_mode == MODE_DEDICATED) {
1169 		if (p_eng->run.tm_tx_only)
1170 			setup_arp(p_eng);
1171 
1172 		p_eng->dat.FRAME_LEN =
1173 		    (uint32_t *)malloc(p_eng->dat.Des_Num * sizeof(uint32_t));
1174 		p_eng->dat.wp_lst =
1175 		    (uint32_t *)malloc(p_eng->dat.Des_Num * sizeof(uint32_t));
1176 
1177 		if (!p_eng->dat.FRAME_LEN)
1178 			return (finish_check(p_eng, Err_Flag_MALLOC_FrmSize));
1179 		if (!p_eng->dat.wp_lst)
1180 			return (finish_check(p_eng, Err_Flag_MALLOC_LastWP));
1181 
1182 		TestingSetup(p_eng);
1183 	} else {
1184 		if (p_eng->arg.GARPNumCnt != 0)
1185 			setup_arp(p_eng);
1186 	}
1187 
1188 	p_eng->run.speed_idx = 0;
1189 	p_eng->io.drv_curr = mac_get_driving_strength(p_eng);
1190 	if (mac_set_scan_boundary(p_eng))
1191 		return (finish_check(p_eng, 0));
1192 
1193 	return 0;
1194 }
1195 
1196 static uint32_t get_time_out_th(MAC_ENGINE *p_eng)
1197 {
1198 	uint32_t time_out;
1199 
1200 	time_out = timeout_th_tbl[p_eng->run.speed_idx];
1201 	if (p_eng->run.TM_WaitStart)
1202 		time_out = time_out * 10000;
1203 
1204 	return time_out;
1205 }
1206 uint32_t test_start(MAC_ENGINE *p_eng, PHY_ENGINE *p_phy_eng)
1207 {
1208 	uint32_t drv, speed;
1209 	int td, rd, tbegin, rbegin, tend, rend;
1210 	int tstep, rstep;
1211 
1212 	uint32_t wrn_flag_allspeed = 0;
1213 	uint32_t err_flag_allspeed = 0;
1214 	uint32_t des_flag_allspeed = 0;
1215 	uint32_t ncsi_flag_allspeed = 0;
1216 
1217 	memset(&p_eng->io.result_history[0][0], 0,
1218 	       sizeof(p_eng->io.result_history));
1219 
1220 	for (speed = 0; speed < 3; speed++) {
1221 		p_eng->flg.print_en = 1;
1222 		p_eng->run.speed_idx = speed;
1223 		mac_set_scan_boundary(p_eng);
1224 		if (0 == p_eng->run.speed_sel[speed]) {
1225 			continue;
1226 		}
1227 
1228 		p_eng->run.timeout_th = get_time_out_th(p_eng);
1229 		if (p_eng->arg.run_mode == MODE_DEDICATED) {
1230 			if ((p_eng->arg.run_speed == SET_1G_100M_10MBPS) ||
1231 			    (p_eng->arg.run_speed == SET_100M_10MBPS)) {
1232 				if (p_eng->run.speed_sel[0])
1233 					p_eng->run.loop_max =
1234 					    p_eng->arg.loop_max;
1235 				else if (p_eng->run.speed_sel[1])
1236 					p_eng->run.loop_max =
1237 					    p_eng->arg.loop_max / 100;
1238 				else
1239 					p_eng->run.loop_max =
1240 					    p_eng->arg.loop_max / 1000;
1241 
1242 				if (0 == p_eng->run.loop_max)
1243 					p_eng->run.loop_max = 1;
1244 
1245 				calc_loop_check_num(p_eng);
1246 			}
1247 			//------------------------------
1248 			// PHY Initial
1249 			//------------------------------
1250 			if (p_phy_eng->fp_set) {
1251 				init_phy(p_eng, p_phy_eng);
1252 			}
1253 
1254 			if (p_eng->flg.error)
1255 				return (finish_check(p_eng, 0));
1256 		}
1257 
1258 		//------------------------------
1259 		// [Start] The loop of different IO strength
1260 		//------------------------------
1261 		debug("drirving scan range: %d ~ %d\n",
1262 		       p_eng->io.drv_lower_bond, p_eng->io.drv_upper_bond);
1263 		for (drv = p_eng->io.drv_lower_bond;
1264 		     drv <= p_eng->io.drv_upper_bond; drv++) {
1265 			if (p_eng->run.IO_MrgChk) {
1266 				if (p_eng->run.TM_IOStrength) {
1267 					mac_set_driving_strength(p_eng, drv);
1268 					p_eng->io.drv_curr = mac_get_driving_strength(p_eng);
1269 				}
1270 
1271 				if (p_eng->run.delay_margin)
1272 					PrintIO_Header(p_eng, FP_LOG);
1273 				if (p_eng->run.TM_IOTiming)
1274 					PrintIO_Header(p_eng, FP_IO);
1275 				PrintIO_Header(p_eng, STD_OUT);
1276 			} else {
1277 				if (p_eng->arg.run_mode == MODE_DEDICATED) {
1278 					Print_Header(p_eng, STD_OUT);
1279 				}
1280 			} // End if (p_eng->run.IO_MrgChk)
1281 
1282 			//------------------------------
1283 			// [Start] The loop of different IO out delay
1284 			//------------------------------
1285 			tbegin = p_eng->io.tx_delay_scan.begin;
1286 			tend = p_eng->io.tx_delay_scan.end;
1287 			tstep = p_eng->io.tx_delay_scan.step;
1288 
1289 			rbegin = p_eng->io.rx_delay_scan.begin;
1290 			rend = p_eng->io.rx_delay_scan.end;
1291 			rstep = p_eng->io.rx_delay_scan.step;
1292 
1293 			for (td = tbegin; td <= tend; td += tstep) {
1294 				p_eng->io.Dly_out = td;
1295 				p_eng->io.Dly_out_selval = td;
1296 				if (p_eng->run.IO_MrgChk) {
1297 					PrintIO_LineS(p_eng, STD_OUT);
1298 				} // End if (p_eng->run.IO_MrgChk)
1299 
1300 				//------------------------------
1301 				// [Start] The loop of different IO in
1302 				// delay
1303 				//------------------------------
1304 				for (rd = rbegin; rd <= rend; rd += rstep) {
1305 					p_eng->io.Dly_in = rd;
1306 					if (p_eng->run.IO_MrgChk) {
1307 						p_eng->io.Dly_in_selval = rd;
1308 						scu_disable_mac(p_eng);
1309 						mac_set_delay(p_eng, rd, td);
1310 						scu_enable_mac(p_eng);
1311 					}
1312 					//------------------------------
1313 					// MAC Initial
1314 					//------------------------------
1315 					init_mac(p_eng);
1316 					if (p_eng->flg.error)
1317 						return (finish_check(p_eng, 0));
1318 
1319 					if (p_eng->arg.run_mode == MODE_NCSI) {
1320 						p_eng->io.result =
1321 						    phy_ncsi(p_eng);
1322 					} else {
1323 						p_eng->io.result = TestingLoop(
1324 						    p_eng,
1325 						    p_eng->run.LOOP_CheckNum);
1326 					}
1327 
1328 					p_eng->io.result_history[rd + 64][td] |=
1329 					    p_eng->io.result;
1330 
1331 					/* Display to Log file and monitor */
1332 					if (p_eng->run.IO_MrgChk) {
1333 						PrintIO_Line(p_eng, STD_OUT);
1334 
1335 						FPri_ErrFlag(p_eng, FP_LOG);
1336 
1337 						p_eng->flg.warn = 0;
1338 						p_eng->flg.error = 0;
1339 						p_eng->flg.desc = 0;
1340 						p_eng->flg.ncsi = 0;
1341 					}
1342 				}
1343 
1344 				if (p_eng->run.IO_MrgChk) {
1345 					if (p_eng->run.TM_IOTiming) {
1346 						PRINTF(FP_IO, "\n");
1347 					}
1348 					printf("\n");
1349 				}
1350 			}
1351 
1352 			if (!p_eng->run.tm_tx_only)
1353 				FPri_ErrFlag(p_eng, FP_LOG);
1354 			if (p_eng->run.TM_IOTiming)
1355 				FPri_ErrFlag(p_eng, FP_IO);
1356 
1357 			FPri_ErrFlag(p_eng, STD_OUT);
1358 
1359 			wrn_flag_allspeed |= p_eng->flg.warn;
1360 			err_flag_allspeed |= p_eng->flg.error;
1361 			des_flag_allspeed |= p_eng->flg.error;
1362 			ncsi_flag_allspeed |= p_eng->flg.error;
1363 			p_eng->flg.warn = 0;
1364 			p_eng->flg.error = 0;
1365 			p_eng->flg.desc = 0;
1366 			p_eng->flg.ncsi = 0;
1367 		}
1368 
1369 		if (p_eng->arg.run_mode == MODE_DEDICATED) {
1370 			if (p_phy_eng->fp_clr != 0)
1371 				recov_phy(p_eng, p_phy_eng);
1372 		}
1373 
1374 		p_eng->run.speed_sel[speed] = 0;
1375 		p_eng->flg.print_en = 0;
1376 	} // End for (speed = 0; speed < 3; speed++)
1377 
1378 	p_eng->flg.warn = wrn_flag_allspeed;
1379 	p_eng->flg.error = err_flag_allspeed;
1380 	p_eng->flg.desc = des_flag_allspeed;
1381 	p_eng->flg.ncsi = ncsi_flag_allspeed;
1382 
1383 	return (finish_check(p_eng, 0));
1384 }
1385 static uint32_t ring_clk(uint32_t reg_offset, uint32_t clk_sel)
1386 {
1387 	uint32_t freq;
1388 
1389 	SCU_WR(0, reg_offset);
1390 	SCU_WR((0xf << 2) | BIT(0), reg_offset);
1391 	udelay(1000);
1392 	SCU_WR((clk_sel << 2) | BIT(1) | BIT(0), reg_offset);
1393 	while ((SCU_RD(reg_offset) & BIT(6)) == 0);
1394 
1395 	freq = (SCU_RD(reg_offset) & GENMASK(29, 16)) >> 16;
1396 	SCU_WR(0, reg_offset);
1397 	return ((freq + 1) * 48828);
1398 }
1399 
1400 void dump_setting(MAC_ENGINE *p_eng)
1401 {
1402 	/* dump env */
1403 	printf("===================\n");
1404 	printf("ast2600 compatible = %d\n", p_eng->env.ast2600);
1405 	printf("ast2500 compatible = %d\n", p_eng->env.ast2500);
1406 	printf("valid MAC number = %d\n", p_eng->env.mac_num);
1407 	printf("use new MDIO register = %d %d %d %d\n",
1408 	       p_eng->env.is_new_mdio_reg[0],
1409 	       p_eng->env.is_new_mdio_reg[1],
1410 	       p_eng->env.is_new_mdio_reg[2],
1411 	       p_eng->env.is_new_mdio_reg[3]);
1412 	printf("1G compatible = %d %d %d %d\n",
1413 	       p_eng->env.is_1g_valid[0],
1414 	       p_eng->env.is_1g_valid[1],
1415 	       p_eng->env.is_1g_valid[2],
1416 	       p_eng->env.is_1g_valid[3]);
1417 	printf("===================\n");
1418 
1419 
1420 #if defined(CONFIG_ASPEED_AST2600)
1421 	printf("RGMIICK of MAC1/2 = %d Hz\n", ring_clk(0x320, 0xf));
1422 	printf("RGMIICK of MAC3/4 = %d Hz\n", ring_clk(0x330, 0x9));
1423 	printf("EPLL              = %d Hz\n", ring_clk(0x320, 0x5) * 4);
1424 	printf("HCLK              = %d Hz\n", ring_clk(0x330, 0x1));
1425 #endif
1426 
1427 }
1428 /**
1429  * @brief nettest main function
1430 */
1431 int mac_test(int argc, char * const argv[], uint32_t mode)
1432 {
1433 	MAC_ENGINE mac_eng;
1434 	PHY_ENGINE phy_eng;
1435 	uint32_t ret;
1436 
1437 	ret = init_mac_engine(&mac_eng, mode);
1438 	if (ret) {
1439 		printf("init MAC engine fail\n");
1440 		return ret;
1441 	}
1442 
1443 	if (argc <= 1) {
1444 		print_usage(&mac_eng);
1445 		return 1;
1446 	}
1447 
1448 	mac_eng.arg.mac_idx = simple_strtol(argv[1], NULL, 16);
1449 
1450 	/* default mdio_idx = mac_idx */
1451 	mac_eng.arg.mdio_idx = mac_eng.arg.mac_idx;
1452 	if (MODE_DEDICATED == mode)
1453 		parse_arg_dedicated(argc, argv, &mac_eng);
1454 	else
1455 		parse_arg_ncsi(argc, argv, &mac_eng);
1456 
1457 	ret = setup_running(&mac_eng);
1458 	if (ret)
1459 		return 1;
1460 
1461 	dump_setting(&mac_eng);
1462 
1463 	/* init PHY engine */
1464 	phy_eng.fp_set = NULL;
1465 	phy_eng.fp_clr = NULL;
1466 
1467 	if (mac_eng.arg.ctrl.b.rmii_50m_out && 0 == mac_eng.run.is_rgmii) {
1468 		mac_set_rmii_50m_output_enable(&mac_eng);
1469 	}
1470 
1471 	push_reg(&mac_eng);
1472 	disable_wdt(&mac_eng);
1473 
1474 	mac_set_addr(&mac_eng);
1475 	if (mac_eng.arg.ctrl.b.mac_int_loopback)
1476 		mac_set_interal_loopback(&mac_eng);
1477 
1478 	scu_set_pinmux(&mac_eng);
1479 
1480 	scu_disable_mac(&mac_eng);
1481 	scu_enable_mac(&mac_eng);
1482 	if (mac_eng.arg.run_mode == MODE_DEDICATED) {
1483 		if (1 == phy_find_addr(&mac_eng)) {
1484 			phy_select(&mac_eng, &phy_eng);
1485 		}
1486 	}
1487 
1488 	/* Data Initial */
1489 	setup_data(&mac_eng);
1490 
1491 	mac_eng.flg.all_fail = 1;
1492 	mac_eng.io.init_done = 1;
1493 	for(int i = 0; i < 3; i++)
1494 		mac_eng.run.speed_sel[i] = mac_eng.run.speed_cfg[i];
1495 
1496 	//------------------------------
1497 	// [Start] The loop of different speed
1498 	//------------------------------
1499 	print_legend();
1500 	test_start(&mac_eng, &phy_eng);
1501 
1502 	return 0;
1503 }
1504