[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