xref: /openbmc/u-boot/drivers/net/pfe_eth/pfe_cmd.c (revision e8f80a5a)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
26281a769SCalvin Johnson /*
36281a769SCalvin Johnson  * Copyright 2015-2016 Freescale Semiconductor, Inc.
46281a769SCalvin Johnson  * Copyright 2017 NXP
56281a769SCalvin Johnson  */
66281a769SCalvin Johnson 
76281a769SCalvin Johnson /*
86281a769SCalvin Johnson  * @file
96281a769SCalvin Johnson  * @brief PFE utility commands
106281a769SCalvin Johnson  */
116281a769SCalvin Johnson 
126281a769SCalvin Johnson #include <net/pfe_eth/pfe_eth.h>
136281a769SCalvin Johnson 
pfe_command_help(void)146281a769SCalvin Johnson static inline void pfe_command_help(void)
156281a769SCalvin Johnson {
166281a769SCalvin Johnson 	printf("Usage: pfe [pe | status | expt ] <options>\n");
176281a769SCalvin Johnson }
186281a769SCalvin Johnson 
pfe_command_pe(int argc,char * const argv[])196281a769SCalvin Johnson static void pfe_command_pe(int argc, char * const argv[])
206281a769SCalvin Johnson {
216281a769SCalvin Johnson 	if (argc >= 3 && strcmp(argv[2], "pmem") == 0) {
226281a769SCalvin Johnson 		if (argc >= 4 && strcmp(argv[3], "read") == 0) {
236281a769SCalvin Johnson 			int i;
246281a769SCalvin Johnson 			int num;
256281a769SCalvin Johnson 			int id;
266281a769SCalvin Johnson 			u32 addr;
276281a769SCalvin Johnson 			u32 size;
286281a769SCalvin Johnson 			u32 val;
296281a769SCalvin Johnson 
306281a769SCalvin Johnson 			if (argc == 7) {
316281a769SCalvin Johnson 				num = simple_strtoul(argv[6], NULL, 0);
326281a769SCalvin Johnson 			} else if (argc == 6) {
336281a769SCalvin Johnson 				num = 1;
346281a769SCalvin Johnson 			} else {
356281a769SCalvin Johnson 				printf("Usage: pfe pe pmem read <id> <addr> [<num>]\n");
366281a769SCalvin Johnson 				return;
376281a769SCalvin Johnson 			}
386281a769SCalvin Johnson 
396281a769SCalvin Johnson 			id = simple_strtoul(argv[4], NULL, 0);
406281a769SCalvin Johnson 			addr = simple_strtoul(argv[5], NULL, 16);
416281a769SCalvin Johnson 			size = 4;
426281a769SCalvin Johnson 
436281a769SCalvin Johnson 			for (i = 0; i < num; i++, addr += 4) {
446281a769SCalvin Johnson 				val = pe_pmem_read(id, addr, size);
456281a769SCalvin Johnson 				val = be32_to_cpu(val);
466281a769SCalvin Johnson 				if (!(i & 3))
476281a769SCalvin Johnson 					printf("%08x: ", addr);
486281a769SCalvin Johnson 				printf("%08x%s", val, i == num - 1 || (i & 3)
496281a769SCalvin Johnson 				       == 3 ? "\n" : " ");
506281a769SCalvin Johnson 			}
516281a769SCalvin Johnson 
526281a769SCalvin Johnson 		} else {
536281a769SCalvin Johnson 			printf("Usage: pfe pe pmem read <parameters>\n");
546281a769SCalvin Johnson 		}
556281a769SCalvin Johnson 	} else if (argc >= 3 && strcmp(argv[2], "dmem") == 0) {
566281a769SCalvin Johnson 		if (argc >= 4 && strcmp(argv[3], "read") == 0) {
576281a769SCalvin Johnson 			int i;
586281a769SCalvin Johnson 			int num;
596281a769SCalvin Johnson 			int id;
606281a769SCalvin Johnson 			u32 addr;
616281a769SCalvin Johnson 			u32 size;
626281a769SCalvin Johnson 			u32 val;
636281a769SCalvin Johnson 
646281a769SCalvin Johnson 			if (argc == 7) {
656281a769SCalvin Johnson 				num = simple_strtoul(argv[6], NULL, 0);
666281a769SCalvin Johnson 			} else if (argc == 6) {
676281a769SCalvin Johnson 				num = 1;
686281a769SCalvin Johnson 			} else {
696281a769SCalvin Johnson 				printf("Usage: pfe pe dmem read <id> <addr> [<num>]\n");
706281a769SCalvin Johnson 				return;
716281a769SCalvin Johnson 			}
726281a769SCalvin Johnson 
736281a769SCalvin Johnson 			id = simple_strtoul(argv[4], NULL, 0);
746281a769SCalvin Johnson 			addr = simple_strtoul(argv[5], NULL, 16);
756281a769SCalvin Johnson 			size = 4;
766281a769SCalvin Johnson 
776281a769SCalvin Johnson 			for (i = 0; i < num; i++, addr += 4) {
786281a769SCalvin Johnson 				val = pe_dmem_read(id, addr, size);
796281a769SCalvin Johnson 				val = be32_to_cpu(val);
806281a769SCalvin Johnson 				if (!(i & 3))
816281a769SCalvin Johnson 					printf("%08x: ", addr);
826281a769SCalvin Johnson 				printf("%08x%s", val, i == num - 1 || (i & 3)
836281a769SCalvin Johnson 				       == 3 ? "\n" : " ");
846281a769SCalvin Johnson 			}
856281a769SCalvin Johnson 
866281a769SCalvin Johnson 		} else if (argc >= 4 && strcmp(argv[3], "write") == 0) {
876281a769SCalvin Johnson 			int id;
886281a769SCalvin Johnson 			u32 val;
896281a769SCalvin Johnson 			u32 addr;
906281a769SCalvin Johnson 			u32 size;
916281a769SCalvin Johnson 
926281a769SCalvin Johnson 			if (argc != 7) {
936281a769SCalvin Johnson 				printf("Usage: pfe pe dmem write <id> <val> <addr>\n");
946281a769SCalvin Johnson 				return;
956281a769SCalvin Johnson 			}
966281a769SCalvin Johnson 
976281a769SCalvin Johnson 			id = simple_strtoul(argv[4], NULL, 0);
986281a769SCalvin Johnson 			val = simple_strtoul(argv[5], NULL, 16);
996281a769SCalvin Johnson 			val = cpu_to_be32(val);
1006281a769SCalvin Johnson 			addr = simple_strtoul(argv[6], NULL, 16);
1016281a769SCalvin Johnson 			size = 4;
1026281a769SCalvin Johnson 			pe_dmem_write(id, val, addr, size);
1036281a769SCalvin Johnson 		} else {
1046281a769SCalvin Johnson 			printf("Usage: pfe pe dmem [read | write] <parameters>\n");
1056281a769SCalvin Johnson 		}
1066281a769SCalvin Johnson 	} else if (argc >= 3 && strcmp(argv[2], "lmem") == 0) {
1076281a769SCalvin Johnson 		if (argc >= 4 && strcmp(argv[3], "read") == 0) {
1086281a769SCalvin Johnson 			int i;
1096281a769SCalvin Johnson 			int num;
1106281a769SCalvin Johnson 			u32 val;
1116281a769SCalvin Johnson 			u32 offset;
1126281a769SCalvin Johnson 
1136281a769SCalvin Johnson 			if (argc == 6) {
1146281a769SCalvin Johnson 				num = simple_strtoul(argv[5], NULL, 0);
1156281a769SCalvin Johnson 			} else if (argc == 5) {
1166281a769SCalvin Johnson 				num = 1;
1176281a769SCalvin Johnson 			} else {
1186281a769SCalvin Johnson 				printf("Usage: pfe pe lmem read <offset> [<num>]\n");
1196281a769SCalvin Johnson 				return;
1206281a769SCalvin Johnson 			}
1216281a769SCalvin Johnson 
1226281a769SCalvin Johnson 			offset = simple_strtoul(argv[4], NULL, 16);
1236281a769SCalvin Johnson 
1246281a769SCalvin Johnson 			for (i = 0; i < num; i++, offset += 4) {
1256281a769SCalvin Johnson 				pe_lmem_read(&val, 4, offset);
1266281a769SCalvin Johnson 				val = be32_to_cpu(val);
1276281a769SCalvin Johnson 				printf("%08x%s", val, i == num - 1 || (i & 7)
1286281a769SCalvin Johnson 				       == 7 ? "\n" : " ");
1296281a769SCalvin Johnson 			}
1306281a769SCalvin Johnson 
1316281a769SCalvin Johnson 		} else if (argc >= 4 && strcmp(argv[3], "write") == 0)	{
1326281a769SCalvin Johnson 			u32 val;
1336281a769SCalvin Johnson 			u32 offset;
1346281a769SCalvin Johnson 
1356281a769SCalvin Johnson 			if (argc != 6) {
1366281a769SCalvin Johnson 				printf("Usage: pfe pe lmem write <val> <offset>\n");
1376281a769SCalvin Johnson 				return;
1386281a769SCalvin Johnson 			}
1396281a769SCalvin Johnson 
1406281a769SCalvin Johnson 			val = simple_strtoul(argv[4], NULL, 16);
1416281a769SCalvin Johnson 			val = cpu_to_be32(val);
1426281a769SCalvin Johnson 			offset = simple_strtoul(argv[5], NULL, 16);
1436281a769SCalvin Johnson 			pe_lmem_write(&val, 4, offset);
1446281a769SCalvin Johnson 		} else {
1456281a769SCalvin Johnson 			printf("Usage: pfe pe lmem [read | write] <parameters>\n");
1466281a769SCalvin Johnson 		}
1476281a769SCalvin Johnson 	} else {
1486281a769SCalvin Johnson 		if (strcmp(argv[2], "help") != 0)
1496281a769SCalvin Johnson 			printf("Unknown option: %s\n", argv[2]);
1506281a769SCalvin Johnson 
1516281a769SCalvin Johnson 		printf("Usage: pfe pe <parameters>\n");
1526281a769SCalvin Johnson 	}
1536281a769SCalvin Johnson }
1546281a769SCalvin Johnson 
1556281a769SCalvin Johnson #define NUM_QUEUES		16
1566281a769SCalvin Johnson 
1576281a769SCalvin Johnson /*
1586281a769SCalvin Johnson  * qm_read_drop_stat
1596281a769SCalvin Johnson  * This function is used to read the drop statistics from the TMU
1606281a769SCalvin Johnson  * hw drop counter.  Since the hw counter is always cleared afer
1616281a769SCalvin Johnson  * reading, this function maintains the previous drop count, and
1626281a769SCalvin Johnson  * adds the new value to it.  That value can be retrieved by
1636281a769SCalvin Johnson  * passing a pointer to it with the total_drops arg.
1646281a769SCalvin Johnson  *
1656281a769SCalvin Johnson  * @param tmu           TMU number (0 - 3)
1666281a769SCalvin Johnson  * @param queue         queue number (0 - 15)
1676281a769SCalvin Johnson  * @param total_drops   pointer to location to store total drops (or NULL)
1686281a769SCalvin Johnson  * @param do_reset      if TRUE, clear total drops after updating
1696281a769SCalvin Johnson  *
1706281a769SCalvin Johnson  */
qm_read_drop_stat(u32 tmu,u32 queue,u32 * total_drops,int do_reset)1716281a769SCalvin Johnson u32 qm_read_drop_stat(u32 tmu, u32 queue, u32 *total_drops, int do_reset)
1726281a769SCalvin Johnson {
1736281a769SCalvin Johnson 	static u32 qtotal[TMU_MAX_ID + 1][NUM_QUEUES];
1746281a769SCalvin Johnson 	u32 val;
1756281a769SCalvin Johnson 
1766281a769SCalvin Johnson 	writel((tmu << 8) | queue, TMU_TEQ_CTRL);
1776281a769SCalvin Johnson 	writel((tmu << 8) | queue, TMU_LLM_CTRL);
1786281a769SCalvin Johnson 	val = readl(TMU_TEQ_DROP_STAT);
1796281a769SCalvin Johnson 	qtotal[tmu][queue] += val;
1806281a769SCalvin Johnson 	if (total_drops)
1816281a769SCalvin Johnson 		*total_drops = qtotal[tmu][queue];
1826281a769SCalvin Johnson 	if (do_reset)
1836281a769SCalvin Johnson 		qtotal[tmu][queue] = 0;
1846281a769SCalvin Johnson 	return val;
1856281a769SCalvin Johnson }
1866281a769SCalvin Johnson 
tmu_queue_stats(char * buf,int tmu,int queue)1876281a769SCalvin Johnson static ssize_t tmu_queue_stats(char *buf, int tmu, int queue)
1886281a769SCalvin Johnson {
1896281a769SCalvin Johnson 	ssize_t len = 0;
1906281a769SCalvin Johnson 	u32 drops;
1916281a769SCalvin Johnson 
1926281a769SCalvin Johnson 	printf("%d-%02d, ", tmu, queue);
1936281a769SCalvin Johnson 
1946281a769SCalvin Johnson 	drops = qm_read_drop_stat(tmu, queue, NULL, 0);
1956281a769SCalvin Johnson 
1966281a769SCalvin Johnson 	/* Select queue */
1976281a769SCalvin Johnson 	writel((tmu << 8) | queue, TMU_TEQ_CTRL);
1986281a769SCalvin Johnson 	writel((tmu << 8) | queue, TMU_LLM_CTRL);
1996281a769SCalvin Johnson 
2006281a769SCalvin Johnson 	printf("(teq) drop: %10u, tx: %10u (llm) head: %08x, tail: %08x, drop: %10u\n",
2016281a769SCalvin Johnson 	       drops, readl(TMU_TEQ_TRANS_STAT),
2026281a769SCalvin Johnson 	       readl(TMU_LLM_QUE_HEADPTR), readl(TMU_LLM_QUE_TAILPTR),
2036281a769SCalvin Johnson 	       readl(TMU_LLM_QUE_DROPCNT));
2046281a769SCalvin Johnson 
2056281a769SCalvin Johnson 	return len;
2066281a769SCalvin Johnson }
2076281a769SCalvin Johnson 
tmu_queues(char * buf,int tmu)2086281a769SCalvin Johnson static ssize_t tmu_queues(char *buf, int tmu)
2096281a769SCalvin Johnson {
2106281a769SCalvin Johnson 	ssize_t len = 0;
2116281a769SCalvin Johnson 	int queue;
2126281a769SCalvin Johnson 
2136281a769SCalvin Johnson 	for (queue = 0; queue < 16; queue++)
2146281a769SCalvin Johnson 		len += tmu_queue_stats(buf + len, tmu, queue);
2156281a769SCalvin Johnson 
2166281a769SCalvin Johnson 	return len;
2176281a769SCalvin Johnson }
2186281a769SCalvin Johnson 
hif_status(void)2196281a769SCalvin Johnson static inline void hif_status(void)
2206281a769SCalvin Johnson {
2216281a769SCalvin Johnson 	printf("hif:\n");
2226281a769SCalvin Johnson 
2236281a769SCalvin Johnson 	printf("  tx curr bd:    %x\n", readl(HIF_TX_CURR_BD_ADDR));
2246281a769SCalvin Johnson 	printf("  tx status:     %x\n", readl(HIF_TX_STATUS));
2256281a769SCalvin Johnson 	printf("  tx dma status: %x\n", readl(HIF_TX_DMA_STATUS));
2266281a769SCalvin Johnson 
2276281a769SCalvin Johnson 	printf("  rx curr bd:    %x\n", readl(HIF_RX_CURR_BD_ADDR));
2286281a769SCalvin Johnson 	printf("  rx status:     %x\n", readl(HIF_RX_STATUS));
2296281a769SCalvin Johnson 	printf("  rx dma status: %x\n", readl(HIF_RX_DMA_STATUS));
2306281a769SCalvin Johnson 
2316281a769SCalvin Johnson 	printf("hif nocopy:\n");
2326281a769SCalvin Johnson 
2336281a769SCalvin Johnson 	printf("  tx curr bd:    %x\n", readl(HIF_NOCPY_TX_CURR_BD_ADDR));
2346281a769SCalvin Johnson 	printf("  tx status:     %x\n", readl(HIF_NOCPY_TX_STATUS));
2356281a769SCalvin Johnson 	printf("  tx dma status: %x\n", readl(HIF_NOCPY_TX_DMA_STATUS));
2366281a769SCalvin Johnson 
2376281a769SCalvin Johnson 	printf("  rx curr bd:    %x\n", readl(HIF_NOCPY_RX_CURR_BD_ADDR));
2386281a769SCalvin Johnson 	printf("  rx status:     %x\n", readl(HIF_NOCPY_RX_STATUS));
2396281a769SCalvin Johnson 	printf("  rx dma status: %x\n", readl(HIF_NOCPY_RX_DMA_STATUS));
2406281a769SCalvin Johnson }
2416281a769SCalvin Johnson 
gpi(int id,void * base)2426281a769SCalvin Johnson static void gpi(int id, void *base)
2436281a769SCalvin Johnson {
2446281a769SCalvin Johnson 	u32 val;
2456281a769SCalvin Johnson 
2466281a769SCalvin Johnson 	printf("%s%d:\n", __func__, id);
2476281a769SCalvin Johnson 
2486281a769SCalvin Johnson 	printf("  tx under stick: %x\n", readl(base + GPI_FIFO_STATUS));
2496281a769SCalvin Johnson 	val = readl(base + GPI_FIFO_DEBUG);
2506281a769SCalvin Johnson 	printf("  tx pkts:        %x\n", (val >> 23) & 0x3f);
2516281a769SCalvin Johnson 	printf("  rx pkts:        %x\n", (val >> 18) & 0x3f);
2526281a769SCalvin Johnson 	printf("  tx bytes:       %x\n", (val >> 9) & 0x1ff);
2536281a769SCalvin Johnson 	printf("  rx bytes:       %x\n", (val >> 0) & 0x1ff);
2546281a769SCalvin Johnson 	printf("  overrun:        %x\n", readl(base + GPI_OVERRUN_DROPCNT));
2556281a769SCalvin Johnson }
2566281a769SCalvin Johnson 
bmu(int id,void * base)2576281a769SCalvin Johnson static void  bmu(int id, void *base)
2586281a769SCalvin Johnson {
2596281a769SCalvin Johnson 	printf("%s%d:\n", __func__, id);
2606281a769SCalvin Johnson 
2616281a769SCalvin Johnson 	printf("  buf size:  %x\n", (1 << readl(base + BMU_BUF_SIZE)));
2626281a769SCalvin Johnson 	printf("  buf count: %x\n", readl(base + BMU_BUF_CNT));
2636281a769SCalvin Johnson 	printf("  buf rem:   %x\n", readl(base + BMU_REM_BUF_CNT));
2646281a769SCalvin Johnson 	printf("  buf curr:  %x\n", readl(base + BMU_CURR_BUF_CNT));
2656281a769SCalvin Johnson 	printf("  free err:  %x\n", readl(base + BMU_FREE_ERR_ADDR));
2666281a769SCalvin Johnson }
2676281a769SCalvin Johnson 
2686281a769SCalvin Johnson #define	PESTATUS_ADDR_CLASS	0x800
2696281a769SCalvin Johnson #define PEMBOX_ADDR_CLASS	0x890
2706281a769SCalvin Johnson #define	PESTATUS_ADDR_TMU	0x80
2716281a769SCalvin Johnson #define PEMBOX_ADDR_TMU		0x290
2726281a769SCalvin Johnson #define	PESTATUS_ADDR_UTIL	0x0
2736281a769SCalvin Johnson 
pfe_pe_status(int argc,char * const argv[])2746281a769SCalvin Johnson static void pfe_pe_status(int argc, char * const argv[])
2756281a769SCalvin Johnson {
2766281a769SCalvin Johnson 	int do_clear = 0;
2776281a769SCalvin Johnson 	u32 id;
2786281a769SCalvin Johnson 	u32 dmem_addr;
2796281a769SCalvin Johnson 	u32 cpu_state;
2806281a769SCalvin Johnson 	u32 activity_counter;
2816281a769SCalvin Johnson 	u32 rx;
2826281a769SCalvin Johnson 	u32 tx;
2836281a769SCalvin Johnson 	u32 drop;
2846281a769SCalvin Johnson 	char statebuf[5];
2856281a769SCalvin Johnson 	u32 class_debug_reg = 0;
2866281a769SCalvin Johnson 
2876281a769SCalvin Johnson 	if (argc == 4 && strcmp(argv[3], "clear") == 0)
2886281a769SCalvin Johnson 		do_clear = 1;
2896281a769SCalvin Johnson 
2906281a769SCalvin Johnson 	for (id = CLASS0_ID; id < MAX_PE; id++) {
2916281a769SCalvin Johnson 		if (id >= TMU0_ID) {
2926281a769SCalvin Johnson 			if (id == TMU2_ID)
2936281a769SCalvin Johnson 				continue;
2946281a769SCalvin Johnson 			if (id == TMU0_ID)
2956281a769SCalvin Johnson 				printf("tmu:\n");
2966281a769SCalvin Johnson 			dmem_addr = PESTATUS_ADDR_TMU;
2976281a769SCalvin Johnson 		} else {
2986281a769SCalvin Johnson 			if (id == CLASS0_ID)
2996281a769SCalvin Johnson 				printf("class:\n");
3006281a769SCalvin Johnson 			dmem_addr = PESTATUS_ADDR_CLASS;
3016281a769SCalvin Johnson 			class_debug_reg = readl(CLASS_PE0_DEBUG + id * 4);
3026281a769SCalvin Johnson 		}
3036281a769SCalvin Johnson 
3046281a769SCalvin Johnson 		cpu_state = pe_dmem_read(id, dmem_addr, 4);
3056281a769SCalvin Johnson 		dmem_addr += 4;
3066281a769SCalvin Johnson 		memcpy(statebuf, (char *)&cpu_state, 4);
3076281a769SCalvin Johnson 		statebuf[4] = '\0';
3086281a769SCalvin Johnson 		activity_counter = pe_dmem_read(id, dmem_addr, 4);
3096281a769SCalvin Johnson 		dmem_addr += 4;
3106281a769SCalvin Johnson 		rx = pe_dmem_read(id, dmem_addr, 4);
3116281a769SCalvin Johnson 		if (do_clear)
3126281a769SCalvin Johnson 			pe_dmem_write(id, 0, dmem_addr, 4);
3136281a769SCalvin Johnson 		dmem_addr += 4;
3146281a769SCalvin Johnson 		tx = pe_dmem_read(id, dmem_addr, 4);
3156281a769SCalvin Johnson 		if (do_clear)
3166281a769SCalvin Johnson 			pe_dmem_write(id, 0, dmem_addr, 4);
3176281a769SCalvin Johnson 		dmem_addr += 4;
3186281a769SCalvin Johnson 		drop = pe_dmem_read(id, dmem_addr, 4);
3196281a769SCalvin Johnson 		if (do_clear)
3206281a769SCalvin Johnson 			pe_dmem_write(id, 0, dmem_addr, 4);
3216281a769SCalvin Johnson 		dmem_addr += 4;
3226281a769SCalvin Johnson 
3236281a769SCalvin Johnson 		if (id >= TMU0_ID) {
3246281a769SCalvin Johnson 			printf("%d: state=%4s ctr=%08x rx=%x qstatus=%x\n",
3256281a769SCalvin Johnson 			       id - TMU0_ID, statebuf,
3266281a769SCalvin Johnson 			       cpu_to_be32(activity_counter),
3276281a769SCalvin Johnson 			       cpu_to_be32(rx), cpu_to_be32(tx));
3286281a769SCalvin Johnson 		} else {
3296281a769SCalvin Johnson 			printf("%d: pc=1%04x ldst=%04x state=%4s ctr=%08x rx=%x tx=%x drop=%x\n",
3306281a769SCalvin Johnson 			       id - CLASS0_ID, class_debug_reg & 0xFFFF,
3316281a769SCalvin Johnson 			       class_debug_reg >> 16,
3326281a769SCalvin Johnson 			       statebuf, cpu_to_be32(activity_counter),
3336281a769SCalvin Johnson 			       cpu_to_be32(rx), cpu_to_be32(tx),
3346281a769SCalvin Johnson 			       cpu_to_be32(drop));
3356281a769SCalvin Johnson 		}
3366281a769SCalvin Johnson 	}
3376281a769SCalvin Johnson }
3386281a769SCalvin Johnson 
pfe_command_status(int argc,char * const argv[])3396281a769SCalvin Johnson static void pfe_command_status(int argc, char * const argv[])
3406281a769SCalvin Johnson {
3416281a769SCalvin Johnson 	if (argc >= 3 && strcmp(argv[2], "pe") == 0) {
3426281a769SCalvin Johnson 		pfe_pe_status(argc, argv);
3436281a769SCalvin Johnson 	} else if (argc == 3 && strcmp(argv[2], "bmu") == 0) {
3446281a769SCalvin Johnson 		bmu(1, BMU1_BASE_ADDR);
3456281a769SCalvin Johnson 		bmu(2, BMU2_BASE_ADDR);
3466281a769SCalvin Johnson 	} else if (argc == 3 && strcmp(argv[2], "hif") == 0) {
3476281a769SCalvin Johnson 		hif_status();
3486281a769SCalvin Johnson 	} else if (argc == 3 && strcmp(argv[2], "gpi") == 0) {
3496281a769SCalvin Johnson 		gpi(0, EGPI1_BASE_ADDR);
3506281a769SCalvin Johnson 		gpi(1, EGPI2_BASE_ADDR);
3516281a769SCalvin Johnson 		gpi(3, HGPI_BASE_ADDR);
3526281a769SCalvin Johnson 	} else if (argc == 3 && strcmp(argv[2], "tmu0_queues") == 0) {
3536281a769SCalvin Johnson 		tmu_queues(NULL, 0);
3546281a769SCalvin Johnson 	} else if (argc == 3 && strcmp(argv[2], "tmu1_queues") == 0) {
3556281a769SCalvin Johnson 		tmu_queues(NULL, 1);
3566281a769SCalvin Johnson 	} else if (argc == 3 && strcmp(argv[2], "tmu3_queues") == 0) {
3576281a769SCalvin Johnson 		tmu_queues(NULL, 3);
3586281a769SCalvin Johnson 	} else {
3596281a769SCalvin Johnson 		printf("Usage: pfe status [pe <clear> | bmu | gpi | hif | tmuX_queues ]\n");
3606281a769SCalvin Johnson 	}
3616281a769SCalvin Johnson }
3626281a769SCalvin Johnson 
3636281a769SCalvin Johnson #define EXPT_DUMP_ADDR 0x1fa8
3646281a769SCalvin Johnson #define EXPT_REG_COUNT 20
3656281a769SCalvin Johnson static const char *register_names[EXPT_REG_COUNT] = {
3666281a769SCalvin Johnson 		"  pc", "ECAS", " EID", "  ED",
3676281a769SCalvin Johnson 		"  sp", "  r1", "  r2", "  r3",
3686281a769SCalvin Johnson 		"  r4", "  r5", "  r6", "  r7",
3696281a769SCalvin Johnson 		"  r8", "  r9", " r10", " r11",
3706281a769SCalvin Johnson 		" r12", " r13", " r14", " r15"
3716281a769SCalvin Johnson };
3726281a769SCalvin Johnson 
pfe_command_expt(int argc,char * const argv[])3736281a769SCalvin Johnson static void pfe_command_expt(int argc, char * const argv[])
3746281a769SCalvin Johnson {
3756281a769SCalvin Johnson 	unsigned int id, i, val, addr;
3766281a769SCalvin Johnson 
3776281a769SCalvin Johnson 	if (argc == 3) {
3786281a769SCalvin Johnson 		id = simple_strtoul(argv[2], NULL, 0);
3796281a769SCalvin Johnson 		addr = EXPT_DUMP_ADDR;
3806281a769SCalvin Johnson 		printf("Exception information for PE %d:\n", id);
3816281a769SCalvin Johnson 		for (i = 0; i < EXPT_REG_COUNT; i++) {
3826281a769SCalvin Johnson 			val = pe_dmem_read(id, addr, 4);
3836281a769SCalvin Johnson 			val = be32_to_cpu(val);
3846281a769SCalvin Johnson 			printf("%s:%08x%s", register_names[i], val,
3856281a769SCalvin Johnson 			       (i & 3) == 3 ? "\n" : " ");
3866281a769SCalvin Johnson 			addr += 4;
3876281a769SCalvin Johnson 		}
3886281a769SCalvin Johnson 	} else {
3896281a769SCalvin Johnson 		printf("Usage: pfe expt <id>\n");
3906281a769SCalvin Johnson 	}
3916281a769SCalvin Johnson }
3926281a769SCalvin Johnson 
3936281a769SCalvin Johnson #ifdef PFE_RESET_WA
3946281a769SCalvin Johnson /*This function sends a dummy packet to HIF through TMU3 */
send_dummy_pkt_to_hif(void)3956281a769SCalvin Johnson static void send_dummy_pkt_to_hif(void)
3966281a769SCalvin Johnson {
3976281a769SCalvin Johnson 	u32 buf;
3986281a769SCalvin Johnson 	static u32 dummy_pkt[] =  {
3996281a769SCalvin Johnson 		0x4200800a, 0x01000003, 0x00018100, 0x00000000,
4006281a769SCalvin Johnson 		0x33221100, 0x2b785544, 0xd73093cb, 0x01000608,
4016281a769SCalvin Johnson 		0x04060008, 0x2b780200, 0xd73093cb, 0x0a01a8c0,
4026281a769SCalvin Johnson 		0x33221100, 0xa8c05544, 0x00000301, 0x00000000,
4036281a769SCalvin Johnson 		0x00000000, 0x00000000, 0x00000000, 0xbe86c51f };
4046281a769SCalvin Johnson 
4056281a769SCalvin Johnson 	/*Allocate BMU2 buffer */
4066281a769SCalvin Johnson 	buf = readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL);
4076281a769SCalvin Johnson 
4086281a769SCalvin Johnson 	debug("Sending a dummy pkt to HIF %x\n", buf);
4096281a769SCalvin Johnson 	buf += 0x80;
4106281a769SCalvin Johnson 	memcpy((void *)DDR_PFE_TO_VIRT(buf), dummy_pkt, sizeof(dummy_pkt));
4116281a769SCalvin Johnson 
4126281a769SCalvin Johnson 	/*Write length and pkt to TMU*/
4136281a769SCalvin Johnson 	writel(0x03000042, TMU_PHY_INQ_PKTPTR);
4146281a769SCalvin Johnson 	writel(buf, TMU_PHY_INQ_PKTINFO);
4156281a769SCalvin Johnson }
4166281a769SCalvin Johnson 
pfe_command_stop(int argc,char * const argv[])4176281a769SCalvin Johnson static void pfe_command_stop(int argc, char * const argv[])
4186281a769SCalvin Johnson {
4196281a769SCalvin Johnson 	int pfe_pe_id, hif_stop_loop = 10;
4206281a769SCalvin Johnson 	u32 rx_status;
4216281a769SCalvin Johnson 
4226281a769SCalvin Johnson 	printf("Stopping PFE...\n");
4236281a769SCalvin Johnson 
4246281a769SCalvin Johnson 	/*Mark all descriptors as LAST_BD */
4256281a769SCalvin Johnson 	hif_rx_desc_disable();
4266281a769SCalvin Johnson 
4276281a769SCalvin Johnson 	/*If HIF Rx BDP is busy send a dummy packet */
4286281a769SCalvin Johnson 	do {
4296281a769SCalvin Johnson 		rx_status = readl(HIF_RX_STATUS);
4306281a769SCalvin Johnson 		if (rx_status & BDP_CSR_RX_DMA_ACTV)
4316281a769SCalvin Johnson 			send_dummy_pkt_to_hif();
4326281a769SCalvin Johnson 		udelay(10);
4336281a769SCalvin Johnson 	} while (hif_stop_loop--);
4346281a769SCalvin Johnson 
4356281a769SCalvin Johnson 	if (readl(HIF_RX_STATUS) & BDP_CSR_RX_DMA_ACTV)
4366281a769SCalvin Johnson 		printf("Unable to stop HIF\n");
4376281a769SCalvin Johnson 
4386281a769SCalvin Johnson 	/*Disable Class PEs */
4396281a769SCalvin Johnson 	for (pfe_pe_id = CLASS0_ID; pfe_pe_id <= CLASS_MAX_ID; pfe_pe_id++) {
4406281a769SCalvin Johnson 		/*Inform PE to stop */
4416281a769SCalvin Johnson 		pe_dmem_write(pfe_pe_id, cpu_to_be32(1), PEMBOX_ADDR_CLASS, 4);
4426281a769SCalvin Johnson 		udelay(10);
4436281a769SCalvin Johnson 
4446281a769SCalvin Johnson 		/*Read status */
4456281a769SCalvin Johnson 		if (!pe_dmem_read(pfe_pe_id, PEMBOX_ADDR_CLASS + 4, 4))
4466281a769SCalvin Johnson 			printf("Failed to stop PE%d\n", pfe_pe_id);
4476281a769SCalvin Johnson 	}
4486281a769SCalvin Johnson 
4496281a769SCalvin Johnson 	/*Disable TMU PEs */
4506281a769SCalvin Johnson 	for (pfe_pe_id = TMU0_ID; pfe_pe_id <= TMU_MAX_ID; pfe_pe_id++) {
4516281a769SCalvin Johnson 		if (pfe_pe_id == TMU2_ID)
4526281a769SCalvin Johnson 			continue;
4536281a769SCalvin Johnson 
4546281a769SCalvin Johnson 		/*Inform PE to stop */
4556281a769SCalvin Johnson 		pe_dmem_write(pfe_pe_id, 1, PEMBOX_ADDR_TMU, 4);
4566281a769SCalvin Johnson 		udelay(10);
4576281a769SCalvin Johnson 
4586281a769SCalvin Johnson 		/*Read status */
4596281a769SCalvin Johnson 		if (!pe_dmem_read(pfe_pe_id, PEMBOX_ADDR_TMU + 4, 4))
4606281a769SCalvin Johnson 			printf("Failed to stop PE%d\n", pfe_pe_id);
4616281a769SCalvin Johnson 	}
4626281a769SCalvin Johnson }
4636281a769SCalvin Johnson #endif
4646281a769SCalvin Johnson 
pfe_command(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])4656281a769SCalvin Johnson static int pfe_command(cmd_tbl_t *cmdtp, int flag, int argc,
4666281a769SCalvin Johnson 		       char * const argv[])
4676281a769SCalvin Johnson {
4686281a769SCalvin Johnson 	if (argc == 1 || strcmp(argv[1], "help") == 0) {
4696281a769SCalvin Johnson 		pfe_command_help();
4706281a769SCalvin Johnson 		return CMD_RET_SUCCESS;
4716281a769SCalvin Johnson 	}
4726281a769SCalvin Johnson 
4736281a769SCalvin Johnson 	if (strcmp(argv[1], "pe") == 0) {
4746281a769SCalvin Johnson 		pfe_command_pe(argc, argv);
4756281a769SCalvin Johnson 	} else if (strcmp(argv[1], "status") == 0) {
4766281a769SCalvin Johnson 		pfe_command_status(argc, argv);
4776281a769SCalvin Johnson 	} else if (strcmp(argv[1], "expt") == 0) {
4786281a769SCalvin Johnson 		pfe_command_expt(argc, argv);
4796281a769SCalvin Johnson #ifdef PFE_RESET_WA
4806281a769SCalvin Johnson 	} else if (strcmp(argv[1], "stop") == 0) {
4816281a769SCalvin Johnson 		pfe_command_stop(argc, argv);
4826281a769SCalvin Johnson #endif
4836281a769SCalvin Johnson 	} else {
4846281a769SCalvin Johnson 		printf("Unknown option: %s\n", argv[1]);
4856281a769SCalvin Johnson 		pfe_command_help();
4866281a769SCalvin Johnson 		return CMD_RET_FAILURE;
4876281a769SCalvin Johnson 	}
4886281a769SCalvin Johnson 	return CMD_RET_SUCCESS;
4896281a769SCalvin Johnson }
4906281a769SCalvin Johnson 
4916281a769SCalvin Johnson U_BOOT_CMD(
4926281a769SCalvin Johnson 	pfe,	7,	1,	pfe_command,
4936281a769SCalvin Johnson 	"Performs PFE lib utility functions",
4946281a769SCalvin Johnson 	"Usage:\n"
4956281a769SCalvin Johnson 	"pfe <options>"
4966281a769SCalvin Johnson );
497