blob: ce03adf5533516bb7a2bf8ed29e7f1746b30c7fa [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/*******************************************************************************
2* °æÈ¨ËùÓÐ (C)2011, ÉîÛÚÊÐÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
3*
4* ÎļþÃû³Æ: net.c
5* Îļþ±êʶ:
6* ÄÚÈÝÕªÒª: ¸ºÔðCPUºÍPPÄ£¿éÖ®¼äµÄÊý¾Ý½»»¥
7* ÆäËü˵Ã÷:
8* µ±Ç°°æ±¾: 1.0
9* ×÷¡¡¡¡Õß: ±«Ð¡ÔÆ
10* Íê³ÉÈÕÆÚ: 2012-1-12 16:22:32
11*
12* Ð޸ļǼ1
13* ÐÞ¸ÄÈÕÆÚ:
14* °æ±¾¡¡ºÅ:
15* Ð޸ġ¡ÈË:
16* ÐÞ¸ÄÄÚÈÝ:
17*
18*******************************************************************************/
19#include <common.h>
20#include <asm/errno.h>
21#include <malloc.h>
22#include <net.h>
23#include <asm/arch/gmac.h>
24
25
26#if 0
27#include <tm/io.h>
28#include <tm/tm.h>
29#include <tm/pon.h>
30#include <tm/pp/dma.h>
31#include <tm/pp/bmu.h>
32#include <tm/pp/red.h>
33#include <tm/pp/pp.h>
34#include <tm/pp/net.h>
35#include <tm/switch/smac.h>
36#endif
37
38
39#ifdef CONFIG_CMD_NET
40
41#define CACHE_ALIGNED(x) ((x)&(~0x1f))
42#if 0
43typedef struct _queue_ctrl{
44 u8 *pFirst;
45 u32 nextToProc;
46} NET_QUEUE_CTRL;
47#endif
48u8 default_mac[6]={0x00,0xd0,0xd0,0x01,0x02,0x03};
49/*NET_QUEUE_CTRL queue_ctrl[PP_MAX_QUEUE];
50int pp_net_debug=0;*/
51
52void (* volatile net_recv) (u8 * buf, int len) = NULL;
53
54void register_net_recv(void *handle)
55{
56 net_recv = handle;
57}
58
59/*
60 * Get pointer to next RX descriptor to be processed by SW
61 */
62 #if 0
63static inline struct pp_desc * pp_get_next_rxdesc(int rxq)
64{
65 struct pp_desc *desc;
66 NET_QUEUE_CTRL *qc;
67 qc = &queue_ctrl[rxq];
68 desc = (struct pp_desc *)(qc->nextToProc * PP_DESC_SIZE + qc->pFirst);
69 if(unlikely(++qc->nextToProc >= PP_QUEUE_SIZE)){
70 qc->nextToProc = 0;
71 }
72 return desc;
73}
74
75static void dump_net_data(u8 *data, u32 len)
76{
77 int i;
78 len = len > 64?64:len;
79 for(i=0;i<len;i++){
80 printf("%.2x ",data[i]);
81 if((i&0xf) == 0xf)
82 printf("\n");
83 }
84 printf("\n");
85}
86
87void dump_desc(struct pp_desc *desc)
88{
89 u32 *data = (u32 *)desc;
90 printf("%.8x:0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",(u32)desc,data[0],data[1],data[2],data[3]);
91 printf("bp %u gem %u len %u\n",desc->BP,desc->Gemport_ID,desc->Pkt_Len);
92}
93
94
95static void free_desc(struct pp_desc *desc,int bp)
96{
97 // free desc
98#ifdef CONFIG_ZX279112
99 if(soft_release_rx_desc(desc->Direction, desc->CPU_Queue_ID,desc->Buffer_Type) < 0)
100#else
101 if(soft_release_rx_desc(desc->CPU_Queue_ID,desc->Buffer_Type) < 0)
102#endif
103 printf("failed to rls rx desc1\n");
104 // free bp
105 if(pp_bmu_free_bp((u16)bp) < 0)
106 printf("failed to rls bp\n");
107}
108
109static inline int pp_net_rx(struct eth_device* dev,int cnt,int rxq)
110{
111 int i,bp,len;
112 struct pp_desc *desc ;
113 u8 *buf;
114
115 // receive packet
116#ifdef CONFIG_SYS_ARM_CACHE_WRITETHROUGH
117 invalidate_dcache_all();
118#endif
119 for(i=0;i<cnt;i++){
120 //get desc, invalid cache, and prefetch
121 desc = pp_get_next_rxdesc(rxq);
122#if !defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) && !defined(CONFIG_SYS_DCACHE_OFF)
123 invalidate_dcache_range((u32)desc,(u32)desc+16);
124#endif
125 bp = desc->BP;
126 // check bp
127 if(unlikely(bp >= BP_NUMBERS)){
128 printf("invalid bp %u\n",bp);
129 dump_desc(desc);
130 //error handle
131#ifdef CONFIG_ZX279112
132 soft_release_rx_desc(desc->Direction, rxq,1);
133#else
134 soft_release_rx_desc(rxq,1);
135#endif
136 continue;
137 }
138 buf = (u8 *)(BP_TO_ADDR(bp)) + desc->Offset;
139 len = desc->Pkt_Len;
140#if !defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) && !defined(CONFIG_SYS_DCACHE_OFF)
141 invalidate_dcache_range((u32)buf,(u32)buf+len);
142#endif
143 if(pp_net_debug>0){
144 dump_desc(desc);
145 printf("receive len %u, BP %d ,gem %d,addr %x\n",len,
146 bp,desc->Gemport_ID,(u32)buf);
147 dump_net_data(buf,len);
148 pp_net_debug--;
149 }
150
151 if(net_recv == NULL)
152 NetReceive(buf, len);
153 else
154 net_recv(buf, len);
155 free_desc(desc,bp);
156 }
157 return cnt;
158}
159
160/*
161 * get the count of unprocess packet
162 */
163static inline int pp_get_rx_cnt(u32 queue)
164{
165 return ZX_REG_READ(PP_DMA_CPU_QUEUE_CNT(queue));
166}
167#endif
168int max_rx_delay=1000;
169/*
170 * pp net poll interface
171 */
172static int gmac_net_poll(struct eth_device* dev)
173{
174 int i,len=0,trxlen=0;
175// unsigned char *rxbuf;
176 unsigned char rxbuf[256];
177
178
179 //for(i=2;i>0;i--)
180 for(i=0;i<2;i++)
181 {
182 if(zx_gmac_getbd(i)!=0)
183 {
184 trxlen=zx_gmac_rx(rxbuf,&len,i);
185 if(net_recv == NULL)
186 NetReceive(rxbuf, trxlen);
187 else
188 net_recv(rxbuf, trxlen);
189 if(zx_gmac_getbd(i)!=0)
190 /* new packet arrived or hardware has update rx cnt, wait for a while */
191 udelay(1);
192 }
193 }
194 return 0;
195}
196#if 0
197int pp_data_raw_send(u8 *data, u32 len,struct pp_desc *desc)
198{
199 int bp;
200 u8 *buf;
201 /* get the tx descriptor */
202 /* alloc bp to save data */
203 if((bp = pp_bmu_alloc_bp())<0){
204 PON_NET_DBG("alloc bp failed\n");
205 return -1;
206 }
207 /* check bp */
208 if(unlikely(bp >= BP_NUMBERS)){
209 PON_NET_DBG("invalid bp %d\n",bp);
210 return -1;
211 }
212 /* copy data to bp */
213 buf = (u8 *)BP_TO_ADDR(bp)+16;
214 memcpy(buf,data,len);
215
216 /* make desc */
217 desc->BP = bp;
218 desc->Pkt_Len = len;
219 desc->Pkt_Len_Changed = len;
220 desc->Offset = 16;
221 if(pp_net_debug>0){
222 printf("send len %u, BP %d ,addr %x\n",len,
223 bp,(u32)buf);
224 dump_desc(desc);
225 dump_net_data(buf,len);
226 pp_net_debug--;
227 }
228
229#if !defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) && !defined(CONFIG_SYS_DCACHE_OFF)
230 flush_dcache_range((u32)buf,(u32)buf+len);
231#endif
232 /* insert desc */
233 if(soft_insert_tx_desc((u32 *)desc)<0){
234 PON_NET_DBG("insert desc failed\n");
235 return -2;
236 }
237 return 0;
238}
239#endif
240/*
241 * send packet to sw,
242 */
243static int gmac_net_sw_tx(struct eth_device* dev, volatile void* packet, int length)
244{
245 if(zx_gmac_send((u8 *)packet,length) != 0)
246 {
247 printf("gmac send error\n");
248 return 1;
249 }
250 return 0;
251}
252#if 0
253void pp_queue_init(void)
254{
255 int i;
256 NET_QUEUE_CTRL *qc;
257 /* init inner rx queue status */
258 for(i=0;i<PP_MAX_QUEUE;i++){
259 qc = &queue_ctrl[i];
260 qc->pFirst = (u8 *)(PP_VA_DESC_BASE + 0x10000 * (PP_RX_QUEUE_OFF+i));
261 qc->nextToProc = 0;
262 }
263}
264#endif
265int gmac_eth_init(struct eth_device* dev, bd_t* bd)
266{
267 zx_gmac_init();
268 return 0;
269}
270
271void gmac_eth_halt(struct eth_device* dev)
272{
273 udelay(100); /* wait for send complete */
274 zx_gmac_stop();
275
276}
277
278/*int pp_net_init(void)
279{
280 tm_set_onu_mac(ONU_MAC1,default_mac);
281 pp_queue_init();
282 return 0;
283}*/
284
285void gmac_net_register(void)
286{
287 struct eth_device *dev;
288
289 dev = malloc(sizeof(*dev));
290 if (!dev) {
291 free(dev);
292 return ;
293 }
294
295 memset(dev, 0, sizeof(*dev));
296
297 dev->init = gmac_eth_init;
298 dev->halt = gmac_eth_halt;
299 dev->send = gmac_net_sw_tx;
300 dev->recv = gmac_net_poll;
301
302 sprintf(dev->name, "eth0");
303
304 /* get mac */
305 if(!eth_getenv_enetaddr("ethaddr", dev->enetaddr)){
306 puts("Please set MAC address\n");
307 }
308 else{
309 memcpy(default_mac,dev->enetaddr,6);
310 }
311
312 eth_register(dev);
313}
314
315#endif