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