[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/boot/common/src/uboot/drivers/gmac/net.c b/boot/common/src/uboot/drivers/gmac/net.c
new file mode 100644
index 0000000..ce03adf
--- /dev/null
+++ b/boot/common/src/uboot/drivers/gmac/net.c
@@ -0,0 +1,315 @@
+/*******************************************************************************

+* °æÈ¨ËùÓÐ (C)2011, ÉîÛÚÊÐÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£

+*

+* ÎļþÃû³Æ:	net.c

+* Îļþ±êʶ:

+* ÄÚÈÝÕªÒª: ¸ºÔðCPUºÍPPÄ£¿éÖ®¼äµÄÊý¾Ý½»»¥

+* ÆäËü˵Ã÷:

+* µ±Ç°°æ±¾:	1.0

+* ×÷¡¡¡¡Õß:	±«Ð¡ÔÆ

+* Íê³ÉÈÕÆÚ: 2012-1-12 16:22:32

+*

+* Ð޸ļǼ1

+* ÐÞ¸ÄÈÕÆÚ:

+* °æ±¾¡¡ºÅ:

+* Ð޸ġ¡ÈË:

+* ÐÞ¸ÄÄÚÈÝ:

+*

+*******************************************************************************/

+#include <common.h>

+#include <asm/errno.h>

+#include <malloc.h>

+#include <net.h>

+#include <asm/arch/gmac.h>

+

+

+#if 0

+#include <tm/io.h>

+#include <tm/tm.h>

+#include <tm/pon.h>

+#include <tm/pp/dma.h>

+#include <tm/pp/bmu.h>

+#include <tm/pp/red.h>

+#include <tm/pp/pp.h>

+#include <tm/pp/net.h>

+#include <tm/switch/smac.h>

+#endif

+

+

+#ifdef CONFIG_CMD_NET

+

+#define CACHE_ALIGNED(x)  ((x)&(~0x1f))

+#if 0

+typedef struct _queue_ctrl{

+	u8  *pFirst;

+	u32  nextToProc;

+} NET_QUEUE_CTRL;

+#endif

+u8 default_mac[6]={0x00,0xd0,0xd0,0x01,0x02,0x03};

+/*NET_QUEUE_CTRL queue_ctrl[PP_MAX_QUEUE];

+int pp_net_debug=0;*/

+

+void (* volatile net_recv) (u8 * buf, int len) = NULL; 

+

+void register_net_recv(void *handle)

+{

+	net_recv = handle;

+}

+

+/*

+ * Get pointer to next RX descriptor to be processed by SW

+ */

+ #if 0

+static inline struct pp_desc * pp_get_next_rxdesc(int rxq)

+{

+	struct pp_desc *desc;

+	NET_QUEUE_CTRL *qc;

+	qc    = &queue_ctrl[rxq];

+	desc  = (struct pp_desc *)(qc->nextToProc * PP_DESC_SIZE + qc->pFirst);

+	if(unlikely(++qc->nextToProc >= PP_QUEUE_SIZE)){

+		qc->nextToProc = 0;

+	}

+	return desc;

+}

+

+static void dump_net_data(u8 *data, u32 len)

+{

+	int i;

+	len = len > 64?64:len;

+	for(i=0;i<len;i++){

+		printf("%.2x ",data[i]);

+		if((i&0xf) == 0xf)

+			printf("\n");

+	}

+	printf("\n");

+}

+

+void dump_desc(struct pp_desc *desc)

+{

+	u32 *data = (u32 *)desc;

+	printf("%.8x:0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",(u32)desc,data[0],data[1],data[2],data[3]);

+	printf("bp %u gem %u len %u\n",desc->BP,desc->Gemport_ID,desc->Pkt_Len);

+}

+

+

+static void free_desc(struct pp_desc *desc,int bp)

+{

+    // free desc  

+#ifdef CONFIG_ZX279112

+    if(soft_release_rx_desc(desc->Direction, desc->CPU_Queue_ID,desc->Buffer_Type) < 0)

+#else

+    if(soft_release_rx_desc(desc->CPU_Queue_ID,desc->Buffer_Type) < 0)

+#endif

+    	printf("failed to rls rx desc1\n");

+    // free bp 

+    if(pp_bmu_free_bp((u16)bp) < 0)

+    	printf("failed to rls bp\n");	    

+}

+

+static inline int pp_net_rx(struct eth_device* dev,int cnt,int rxq)

+{

+	int i,bp,len;

+	struct pp_desc *desc ;

+	u8 *buf;

+	

+	// receive packet 

+#ifdef CONFIG_SYS_ARM_CACHE_WRITETHROUGH	

+	invalidate_dcache_all();

+#endif	

+	for(i=0;i<cnt;i++){

+		//get desc, invalid cache, and prefetch 

+		desc = pp_get_next_rxdesc(rxq);

+#if !defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) && !defined(CONFIG_SYS_DCACHE_OFF)    

+		invalidate_dcache_range((u32)desc,(u32)desc+16);

+#endif		

+		bp  = desc->BP;

+		// check bp 

+		if(unlikely(bp >= BP_NUMBERS)){

+			printf("invalid bp %u\n",bp);

+			dump_desc(desc);

+			//error handle  

+#ifdef CONFIG_ZX279112

+		    soft_release_rx_desc(desc->Direction, rxq,1);

+#else

+		    soft_release_rx_desc(rxq,1);

+#endif

+		    continue;

+		}

+		buf = (u8 *)(BP_TO_ADDR(bp)) + desc->Offset;

+		len = desc->Pkt_Len;

+#if !defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) && !defined(CONFIG_SYS_DCACHE_OFF)    

+		invalidate_dcache_range((u32)buf,(u32)buf+len);

+#endif		

+        if(pp_net_debug>0){

+        	dump_desc(desc);

+    		printf("receive len %u, BP %d ,gem %d,addr %x\n",len,

+    			bp,desc->Gemport_ID,(u32)buf);

+    		dump_net_data(buf,len);

+    		pp_net_debug--;

+    	}

+

+        if(net_recv == NULL)

+			NetReceive(buf, len);

+		else

+			net_recv(buf, len);

+        free_desc(desc,bp);

+	}

+	return cnt;

+}

+

+/*

+ * get the count of unprocess packet

+ */

+static inline int pp_get_rx_cnt(u32 queue)

+{

+	return ZX_REG_READ(PP_DMA_CPU_QUEUE_CNT(queue));

+}

+#endif

+int max_rx_delay=1000;

+/*

+ * pp net poll interface

+ */

+static int gmac_net_poll(struct eth_device* dev)

+{

+	int i,len=0,trxlen=0;

+//   	unsigned char  *rxbuf;

+	unsigned char  rxbuf[256];

+

+	

+	//for(i=2;i>0;i--)

+	for(i=0;i<2;i++)

+	{

+		if(zx_gmac_getbd(i)!=0)

+			{

+				trxlen=zx_gmac_rx(rxbuf,&len,i);

+				if(net_recv == NULL)

+				NetReceive(rxbuf, trxlen);

+				else

+				net_recv(rxbuf, trxlen);

+				if(zx_gmac_getbd(i)!=0)

+				/* new packet arrived or hardware has update rx cnt, wait for a while */

+				udelay(1);

+			}

+	}

+    return 0;

+}

+#if 0

+int pp_data_raw_send(u8 *data, u32 len,struct pp_desc *desc)

+{

+	int bp;

+	u8 *buf;

+	/* get the tx descriptor */

+	/* alloc bp to save data */

+	if((bp = pp_bmu_alloc_bp())<0){

+		PON_NET_DBG("alloc bp failed\n");

+		return -1;

+	}

+	/* check bp */

+	if(unlikely(bp >= BP_NUMBERS)){

+		PON_NET_DBG("invalid bp %d\n",bp);

+		return -1;

+	}	

+	/* copy data to bp */

+	buf = (u8 *)BP_TO_ADDR(bp)+16;

+	memcpy(buf,data,len);

+

+	/* make desc */

+	desc->BP              = bp;

+	desc->Pkt_Len         = len;

+	desc->Pkt_Len_Changed = len;

+	desc->Offset          = 16;

+    if(pp_net_debug>0){

+    	printf("send len %u, BP %d ,addr %x\n",len,

+    		bp,(u32)buf);

+    	dump_desc(desc);

+    	dump_net_data(buf,len);

+    	pp_net_debug--;

+    }	

+	

+#if !defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) && !defined(CONFIG_SYS_DCACHE_OFF)    

+    flush_dcache_range((u32)buf,(u32)buf+len);

+#endif    

+	/* insert desc */

+	if(soft_insert_tx_desc((u32 *)desc)<0){

+		PON_NET_DBG("insert desc failed\n");

+		return -2;		

+	}

+	return 0;	    

+}

+#endif

+/* 

+ * send packet to sw, 

+ */

+static int gmac_net_sw_tx(struct eth_device* dev, volatile void* packet, int length)

+{

+	if(zx_gmac_send((u8 *)packet,length) != 0)

+	{

+		printf("gmac send error\n");

+		return 1;

+	}

+	return 0;

+}

+#if 0

+void pp_queue_init(void)

+{

+	int i;

+	NET_QUEUE_CTRL *qc;

+	/* init inner rx queue status */

+	for(i=0;i<PP_MAX_QUEUE;i++){

+		qc = &queue_ctrl[i];

+		qc->pFirst      = (u8 *)(PP_VA_DESC_BASE + 0x10000 * (PP_RX_QUEUE_OFF+i));

+		qc->nextToProc  = 0;

+	}

+}

+#endif

+int  gmac_eth_init(struct eth_device* dev, bd_t* bd)

+{	

+	zx_gmac_init();	

+	return 0;

+}

+

+void gmac_eth_halt(struct eth_device* dev)

+{

+	udelay(100); /* wait for send complete */

+	zx_gmac_stop();	

+

+}

+

+/*int pp_net_init(void)

+{

+    tm_set_onu_mac(ONU_MAC1,default_mac);

+	pp_queue_init();

+	return 0;

+}*/

+

+void gmac_net_register(void)

+{

+	struct eth_device *dev;

+

+	dev = malloc(sizeof(*dev));

+	if (!dev)	{

+		free(dev);

+		return ;

+	}

+

+	memset(dev, 0, sizeof(*dev));

+

+	dev->init 	= gmac_eth_init;

+	dev->halt 	= gmac_eth_halt;

+	dev->send 	= gmac_net_sw_tx;

+	dev->recv 	= gmac_net_poll;

+

+	sprintf(dev->name, "eth0");

+

+	/* get mac */

+	if(!eth_getenv_enetaddr("ethaddr", dev->enetaddr)){

+		puts("Please set MAC address\n");

+	}

+	else{

+		memcpy(default_mac,dev->enetaddr,6);

+	}

+

+	eth_register(dev);

+}

+

+#endif