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