1 #include <rthw.h>
2 #include <rtthread.h>
3 #include <netif/ethernetif.h>
4
5 #include "sam7x_emac.h"
6 #include "AT91SAM7X256.h"
7 #include "lwipopts.h"
8 #include "lwip/mem.h"
9
10 #define MAX_ADDR_LEN 6
11
12 #ifdef DM9161
13 #define EMAC_PIO_CFG (AT91C_PB8_EMDC | \
14 AT91C_PB9_EMDIO | \
15 AT91C_PB2_ETX0 | \
16 AT91C_PB3_ETX1 | \
17 AT91C_PB10_ETX2 | \
18 AT91C_PB11_ETX3 | \
19 AT91C_PB1_ETXEN | \
20 AT91C_PB0_ETXCK_EREFCK | \
21 AT91C_PB15_ERXDV_ECRSDV | \
22 AT91C_PB5_ERX0 | \
23 AT91C_PB6_ERX1 | \
24 AT91C_PB12_ETXER | \
25 AT91C_PB13_ERX2 | \
26 AT91C_PB14_ERX3 | \
27 AT91C_PB17_ERXCK | \
28 AT91C_PB16_ECOL | \
29 AT91C_PB4_ECRS | \
30 AT91C_PB7_ERXER)
31 #else
32 #define EMAC_PIO_CFG (AT91C_PB0_ETXCK_EREFCK | \
33 AT91C_PB1_ETXEN | \
34 AT91C_PB2_ETX0 | \
35 AT91C_PB3_ETX1 | \
36 AT91C_PB4_ECRS | \
37 AT91C_PB5_ERX0 | \
38 AT91C_PB6_ERX1 | \
39 AT91C_PB7_ERXER | \
40 AT91C_PB8_EMDC | \
41 AT91C_PB9_EMDIO | \
42 AT91C_PB10_ETX2 | \
43 AT91C_PB11_ETX3 | \
44 AT91C_PB10_ETX2 | \
45 AT91C_PB13_ERX2 | \
46 AT91C_PB14_ERX3 | \
47 AT91C_PB15_ERXDV_ECRSDV| \
48 AT91C_PB16_ECOL | \
49 AT91C_PB17_ERXCK)
50 #endif
51
52 #define RB_BUFFER_SIZE 8 /* max number of receive buffers */
53 #define ETH_RX_BUF_SIZE 128
54
55 #define TB_BUFFER_SIZE 4
56 #define ETH_TX_BUF_SIZE (PBUF_POOL_BUFSIZE)
57
58 struct rbf_t
59 {
60 rt_uint32_t addr;
61 rt_uint32_t status;
62 };
63
64 static rt_uint32_t current_rb_index; /* current receive buffer index */
65 static volatile struct rbf_t rb_descriptors[RB_BUFFER_SIZE];
66 static volatile struct rbf_t tb_descriptors[TB_BUFFER_SIZE];
67 static rt_uint8_t rx_buf[RB_BUFFER_SIZE][ETH_RX_BUF_SIZE] __attribute__ ((aligned (8)));
68 static rt_uint8_t tx_buf[TB_BUFFER_SIZE][ETH_TX_BUF_SIZE] __attribute__ ((aligned (8)));
69 static struct rt_semaphore tx_sem;
70
71 struct net_device
72 {
73 /* inherit from ethernet device */
74 struct eth_device parent;
75
76 /* interface address info. */
77 rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */
78 };
79 static struct net_device sam7x_dev_entry;
80 static struct net_device *sam7x_dev =&sam7x_dev_entry;
81 AT91PS_EMAC pEmac = AT91C_BASE_EMAC;
82
write_phy(rt_uint8_t addr,rt_uint32_t value)83 rt_inline void write_phy(rt_uint8_t addr, rt_uint32_t value)
84 {
85 AT91C_BASE_EMAC->EMAC_MAN = ((0x01<<30) | (2 << 16) | (1 << 28) |
86 (AT91C_PHY_ADDR << 23) | (addr << 18)) | value;
87 /* Wait until IDLE bit in Network Status register is cleared */
88 while (!(AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE));
89 }
90
read_phy(rt_uint8_t addr)91 rt_inline rt_uint32_t read_phy(rt_uint8_t addr)
92 {
93 AT91C_BASE_EMAC->EMAC_MAN = (0x01<<30) | (0x02 << 16) | (0x02 << 28) |
94 (AT91C_PHY_ADDR << 23) | (addr << 18);
95
96 /* Wait until IDLE bit in Network Status register is cleared */
97 while (!(AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE));
98
99 return (AT91C_BASE_EMAC->EMAC_MAN & 0x0000ffff);
100 }
101
sam7xether_reset_tx_desc(void)102 rt_inline void sam7xether_reset_tx_desc(void)
103 {
104 static rt_uint32_t index = 0;
105
106 if(tb_descriptors[index].status & TxDESC_STATUS_USED)
107 {
108 while(!(tb_descriptors[index].status & TxDESC_STATUS_LAST_BUF))
109 {
110 index ++;
111 if(index >= TB_BUFFER_SIZE)index = 0;
112
113 tb_descriptors[index].status |= TxDESC_STATUS_USED;
114 }
115
116 index ++;
117 if(index >= TB_BUFFER_SIZE)index = 0;
118 }
119 }
120
121
122 /* interrupt service routing */
sam7xether_isr(int irq,void * param)123 static void sam7xether_isr(int irq, void* param)
124 {
125 /* Variable definitions can be made now. */
126 volatile rt_uint32_t isr, rsr;
127
128 /* get status */
129 isr = AT91C_BASE_EMAC->EMAC_ISR;
130 rsr = AT91C_BASE_EMAC->EMAC_RSR;
131
132 if( ( isr & AT91C_EMAC_RCOMP ) || ( rsr & AT91C_EMAC_REC ) )
133 {
134 rt_err_t result;
135
136 /* a frame has been received */
137 result = eth_device_ready((struct eth_device*)&(sam7x_dev->parent));
138 RT_ASSERT(result == RT_EOK);
139
140 AT91C_BASE_EMAC->EMAC_RSR = AT91C_EMAC_REC;
141 }
142
143 if( isr & AT91C_EMAC_TCOMP )
144 {
145 /* A frame has been transmitted. Mark all the buffers as free */
146 sam7xether_reset_tx_desc();
147
148 AT91C_BASE_EMAC->EMAC_TSR = AT91C_EMAC_COMP;
149 }
150 }
151
linksetup(void)152 rt_inline void linksetup(void)
153 {
154 rt_uint32_t value, tout, id1, id2;
155 #ifdef DM9161
156 rt_uint32_t ulBMSR,ulBMCR,i;
157 #endif
158
159 #ifdef DM9161
160 //PHY has internal pull down : disable MII isolate
161 tout = read_phy(PHY_REG_BMCR);
162 tout = read_phy(PHY_REG_BMCR);
163 tout &= ~BMCR_ISOLATE;
164 write_phy(PHY_REG_BMCR, tout);
165
166 /* Check if this is a RTL8201 or DM9161 PHY. */
167 id1 = read_phy(PHY_REG_PHYID1);
168 id2 = read_phy(PHY_REG_PHYID2);
169
170 if (((id1 << 16) | (id2 & 0xfff0)) == MII_DM9161_ID)
171 {
172 rt_kprintf("read MII_DM9161_ID ok!\n");
173
174 tout = DM9161_NP | DM9161_TX_FDX | DM9161_TX_HDX |
175 DM9161_10_FDX | DM9161_10_HDX | DM9161_AN_IEEE_802_3;
176 write_phy(PHY_REG_ANAR, tout);
177 // Wait for PHY auto negotiation completed
178 i = 0;
179 do {
180 ulBMSR = read_phy(PHY_REG_BMSR);
181 ulBMSR = read_phy(PHY_REG_BMSR);
182 i++;
183
184 if(i >= 0xffff)
185 break;
186 }while (!(ulBMSR & BMSR_ANEGCOMPLETE));
187
188 if(i >= 0xffff)
189 rt_kprintf("PHY No Link!\n");
190 else
191 rt_kprintf("PHY auto negotiation completed!\n");
192
193 /* Update the MAC register NCFGR. */
194 AT91C_BASE_EMAC->EMAC_NCFGR = 0;
195 ulBMCR = read_phy(PHY_REG_BMCR);
196
197 if (ulBMCR & BMCR_ANENABLE)
198 {
199 /* AutoNegotiation is enabled. */
200 if(!(ulBMSR & BMSR_ANEGCOMPLETE))
201 {
202 /* Auto-negotitation in progress. */
203 rt_kprintf("Auto-negotitation in progress!\n");
204 return;
205 }
206
207 if (ulBMCR & BMCR_SPEED100)
208 {
209 /* Speed 100Mbit is enabled. */
210 AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_SPD;
211
212 }
213 if (ulBMCR & BMCR_FULLDPLX)
214 {
215 /* Full duplex is enabled. */
216 AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_FD;
217 }
218 }
219 }
220 #else
221 /* Check if this is a RTL8201 or DM9161 PHY. */
222 id1 = read_phy(PHY_REG_PHYID1);
223 id2 = read_phy(PHY_REG_PHYID2);
224
225 if (((id2 << 16) | (id1 & 0xfff0)) == MII_RTL8201_ID)
226 {
227 rt_kprintf("read MII_RTL8201_ID ok!\n");
228
229
230 /* Configure the PHY device */
231 /* Use autonegotiation about the link speed. */
232 write_phy (PHY_REG_BMCR, PHY_AUTO_NEG);
233
234 /* Wait to complete Auto_Negotiation. */
235 for (tout = 0; tout < 0x100000; tout++)
236 {
237 value = read_phy (PHY_REG_BMSR);
238 if (value & BMSR_ANEGCOMPLETE) break; /* autonegotiation finished. */
239 }
240
241 /* Check the link status. */
242 for (tout = 0; tout < 0x10000; tout++)
243 {
244 value = read_phy (PHY_REG_BMSR);
245 if (value & BMSR_LINKST) break; /* Link is on. */
246 }
247 }
248 value = read_phy (PHY_REG_ANLPAR);
249
250 /* Update the MAC register NCFGR. */
251 AT91C_BASE_EMAC->EMAC_NCFGR &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
252
253 /* set full duplex . */
254 if (value & 0xA000) AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_FD;
255 /* set speed */
256 if (value & 0xC000) AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_SPD;
257 #endif
258 }
259
260 /*
261 * Set the MAC address.
262 */
update_mac_address(struct net_device * device)263 rt_inline void update_mac_address(struct net_device* device)
264 {
265 AT91C_BASE_EMAC->EMAC_SA1L = (device->dev_addr[3] << 24) |
266 (device->dev_addr[2] << 16) |
267 (device->dev_addr[1] << 8) |
268 device->dev_addr[0];
269 AT91C_BASE_EMAC->EMAC_SA1H = (device->dev_addr[5] << 8) |
270 device->dev_addr[4];
271 }
272
sam7xether_desc_init()273 rt_inline void sam7xether_desc_init()
274 {
275 rt_uint32_t i;
276
277 /* Rx Buffer Descriptor initialization */
278 current_rb_index = 0;
279 for (i = 0; i < RB_BUFFER_SIZE; i++)
280 {
281 rb_descriptors[i].addr = (rt_uint32_t)&(rx_buf[i][0]);
282 rb_descriptors[i].status = 0;
283 }
284 /* Set the WRAP bit at the end of the list descriptor. */
285 rb_descriptors[RB_BUFFER_SIZE-1].addr |= 0x02;
286 /* Set Rx Queue pointer to descriptor list. */
287 AT91C_BASE_EMAC->EMAC_RBQP = (unsigned int)&(rb_descriptors[0]);
288
289 /* Tx Buffer Descriptor initialization */
290 for (i = 0; i < TB_BUFFER_SIZE; i++)
291 {
292 tb_descriptors[i].addr = (rt_uint32_t)&(tx_buf[i][0]);
293 tb_descriptors[i].status = TxDESC_STATUS_USED;
294 }
295 /* Set the WRAP bit at the end of the list descriptor. */
296 tb_descriptors[TB_BUFFER_SIZE-1].status |= TxDESC_STATUS_WRAP;
297 /* Set Tx Queue pointer to descriptor list. */
298 AT91C_BASE_EMAC->EMAC_TBQP = (unsigned int)&(tb_descriptors[0]);
299 }
300
301 /* RT-Thread Device Interface */
302
303 /* initialize the interface */
sam7xether_init(rt_device_t dev)304 rt_err_t sam7xether_init(rt_device_t dev)
305 {
306 rt_uint32_t i;
307
308 /* enable peripheral clock for EMAC and PIO B */
309 AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOB | 1 << AT91C_ID_EMAC;
310
311 /* Disable pull up on RXDV => PHY normal mode (not in test mode), */
312 /* and set MII mode. PHY has internal pull down. */
313 AT91C_BASE_PIOB->PIO_PPUDR = (1<<16) | (1 << 15);
314
315 /* Clear PB18 <=> PHY powerdown */
316 AT91C_BASE_PIOB->PIO_PER = 1<<18;
317 AT91C_BASE_PIOB->PIO_OER = 1<<18;
318 AT91C_BASE_PIOB->PIO_CODR = 1<<18;
319
320 /* EMAC IO init for EMAC-PHY communication. */
321 AT91C_BASE_PIOB->PIO_ASR = EMAC_PIO_CFG;
322 AT91C_BASE_PIOB->PIO_PDR = EMAC_PIO_CFG; // Set in Periph mode
323
324 /* Enable communication between EMAC-PHY. */
325 AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE;
326 /* MDC = MCK/32 */
327 AT91C_BASE_EMAC->EMAC_NCFGR |= 2<<10;
328
329 /* Reset PHY */
330 AT91C_BASE_PIOB->PIO_PPUDR = AT91C_PB7_ERXER;
331
332 AT91C_BASE_RSTC->RSTC_RMR = 0xA5000000 | (0x08 << 8) ;
333 AT91C_BASE_RSTC->RSTC_RCR = 0xA5000000 | AT91C_RSTC_EXTRST;
334
335 i = 0;
336 while(!(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL))
337 {
338 i++;
339 if(i >= 0xfffff)
340 break;
341 }
342
343 for(i=0; i<0xfffff; i++);//* �ȴ�һ��ָ����ʱ�䣬ʹPHY����
344
345 linksetup();
346
347 rt_kprintf("linksetup ok!\n");
348
349 /* Disable management port in MAC control register. */
350 AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;
351
352 /* Enable EMAC in MII mode, enable clock ERXCK and ETXCK */
353 AT91C_BASE_EMAC->EMAC_USRIO= AT91C_EMAC_CLKEN;
354
355 /* Transmit and Receive disable. */
356 AT91C_BASE_EMAC->EMAC_NCR &= ~(AT91C_EMAC_RE | AT91C_EMAC_TE);
357
358 /* init descriptor */
359 sam7xether_desc_init();
360
361 /* Clear receive and transmit status registers. */
362 AT91C_BASE_EMAC->EMAC_RSR = (AT91C_EMAC_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
363 AT91C_BASE_EMAC->EMAC_TSR = (AT91C_EMAC_UND | AT91C_EMAC_COMP| AT91C_EMAC_BEX |
364 AT91C_EMAC_RLES| AT91C_EMAC_COL | AT91C_EMAC_UBR);
365
366 /* Configure EMAC operation mode. */
367 //AT91C_BASE_EMAC->EMAC_NCFGR |= (AT91C_EMAC_BIG | AT91C_EMAC_DRFCS);
368 // ����������Ч֡�����ջ����� *������FCS�ֶ� �����չ㲥֡ ������1526�ֽڳ�֡
369 AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_CAF |AT91C_EMAC_DRFCS | AT91C_EMAC_NBC | AT91C_EMAC_BIG;
370 AT91C_BASE_EMAC->EMAC_NCR |= (AT91C_EMAC_TE | AT91C_EMAC_RE | AT91C_EMAC_WESTAT);
371
372 /* update MAC address */
373 update_mac_address(sam7x_dev);
374
375 /* enable interrupt */
376 AT91C_BASE_EMAC->EMAC_IDR = 0x3fff;
377 AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP | AT91C_EMAC_TCOMP;
378
379 /* setup interrupt */
380 rt_hw_interrupt_install(AT91C_ID_EMAC, sam7xether_isr, RT_NULL, "emac");
381 *(volatile unsigned int*)(0xFFFFF000 + AT91C_ID_EMAC * 4) = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5;
382 // AT91C_AIC_SMR(AT91C_ID_EMAC) = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5;
383 rt_hw_interrupt_umask(AT91C_ID_EMAC);
384
385 return RT_EOK;
386 }
387
388 /* control the interface */
sam7xether_control(rt_device_t dev,int cmd,void * args)389 rt_err_t sam7xether_control(rt_device_t dev, int cmd, void *args)
390 {
391 switch(cmd)
392 {
393 case NIOCTL_GADDR:
394 /* get mac address */
395 if(args) rt_memcpy(args, sam7x_dev_entry.dev_addr, 6);
396 else return -RT_ERROR;
397 break;
398
399 default :
400 break;
401 }
402
403 return RT_EOK;
404 }
405
406 /* Open the ethernet interface */
sam7xether_open(rt_device_t dev,rt_uint16_t oflags)407 rt_err_t sam7xether_open(rt_device_t dev, rt_uint16_t oflags)
408 {
409 return RT_EOK;
410 }
411
412 /* Close the interface */
sam7xether_close(rt_device_t dev)413 rt_err_t sam7xether_close(rt_device_t dev)
414 {
415 return RT_EOK;
416 }
417
418 /* Read */
sam7xether_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)419 rt_size_t sam7xether_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
420 {
421 rt_set_errno(-RT_ENOSYS);
422 return 0;
423 }
424
425 /* Write */
sam7xether_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)426 rt_size_t sam7xether_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
427 {
428 rt_set_errno(-RT_ENOSYS);
429 return 0;
430 }
431
432 /* See the header file for descriptions of public functions. */
sam7xether_write_frame(rt_uint8_t * ptr,rt_uint32_t length,rt_bool_t eof)433 void sam7xether_write_frame(rt_uint8_t *ptr, rt_uint32_t length, rt_bool_t eof)
434 {
435 rt_uint8_t *buf_ptr;
436 static rt_uint32_t current_tb_index = 0;
437 rt_uint32_t is_last, tx_offset = 0, remain, pdu_length;
438
439 while(tx_offset < length)
440 {
441 /* check whether buffer is available */
442 while(!(tb_descriptors[current_tb_index].status & TxDESC_STATUS_USED))
443 {
444 /* no buffer */
445 rt_thread_delay(5);
446 }
447
448 /* Get the address of the buffer from the descriptor, then copy
449 the data into the buffer. */
450 buf_ptr = (rt_uint8_t *)tb_descriptors[current_tb_index].addr;
451
452 /* How much can we write to the buffer? */
453 remain = length - tx_offset;
454 pdu_length = (remain <= ETH_TX_BUF_SIZE)? remain : ETH_TX_BUF_SIZE;
455
456 /* Copy the data into the buffer. */
457 rt_memcpy(buf_ptr, &ptr[tx_offset], pdu_length );
458 tx_offset += pdu_length;
459
460 /* Is this the last data for the frame? */
461 if((eof == RT_TRUE) && ( tx_offset >= length )) is_last = TxDESC_STATUS_LAST_BUF;
462 else is_last = 0;
463
464 /* Fill out the necessary in the descriptor to get the data sent,
465 then move to the next descriptor, wrapping if necessary. */
466 if(current_tb_index >= (TB_BUFFER_SIZE - 1))
467 {
468 tb_descriptors[current_tb_index].status = ( pdu_length & TxDESC_STATUS_BUF_SIZE )
469 | is_last
470 | TxDESC_STATUS_WRAP;
471 current_tb_index = 0;
472 }
473 else
474 {
475 tb_descriptors[current_tb_index].status = ( pdu_length & TxDESC_STATUS_BUF_SIZE )
476 | is_last;
477 current_tb_index++;
478 }
479
480 /* If this is the last buffer to be sent for this frame we can
481 start the transmission. */
482 if(is_last)
483 {
484 AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART;
485 }
486 }
487 }
488
489 /* ethernet device interface */
490 /*
491 * Transmit packet.
492 */
sam7xether_tx(rt_device_t dev,struct pbuf * p)493 rt_err_t sam7xether_tx( rt_device_t dev, struct pbuf* p)
494 {
495 struct pbuf* q;
496
497 /* lock tx operation */
498 rt_sem_take(&tx_sem, RT_WAITING_FOREVER);
499
500 for (q = p; q != NULL; q = q->next)
501 {
502 if (q->next == RT_NULL) sam7xether_write_frame(q->payload, q->len, RT_TRUE);
503 else sam7xether_write_frame(q->payload, q->len, RT_FALSE);
504 }
505
506 rt_sem_release(&tx_sem);
507
508 return 0;
509 }
510
sam7xether_read_frame(rt_uint8_t * ptr,rt_uint32_t section_length,rt_uint32_t total)511 void sam7xether_read_frame(rt_uint8_t* ptr, rt_uint32_t section_length, rt_uint32_t total)
512 {
513 static rt_uint8_t* src_ptr;
514 register rt_uint32_t buf_remain, section_remain;
515 static rt_uint32_t section_read = 0, buf_offset = 0, frame_read = 0;
516
517 if(ptr == RT_NULL)
518 {
519 /* Reset our state variables ready for the next read from this buffer. */
520 src_ptr = (rt_uint8_t *)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
521 frame_read = (rt_uint32_t)0;
522 buf_offset = (rt_uint32_t)0;
523 }
524 else
525 {
526 /* Loop until we have obtained the required amount of data. */
527 section_read = 0;
528 while( section_read < section_length )
529 {
530 buf_remain = (ETH_RX_BUF_SIZE - buf_offset);
531 section_remain = section_length - section_read;
532
533 if( section_remain > buf_remain )
534 {
535 /* more data on section than buffer size */
536 rt_memcpy(&ptr[ section_read ], &src_ptr[buf_offset], buf_remain);
537 section_read += buf_remain;
538 frame_read += buf_remain;
539
540 /* free buffer */
541 rb_descriptors[current_rb_index].addr &= ~RxDESC_FLAG_OWNSHIP;
542
543 /* move to the next frame. */
544 current_rb_index++;
545 if(current_rb_index >= RB_BUFFER_SIZE) current_rb_index = 0;
546
547 /* Reset the variables for the new buffer. */
548 src_ptr = (rt_uint8_t *)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
549 buf_offset = 0;
550 }
551 else
552 {
553 /* more data on buffer than section size */
554 rt_memcpy(&ptr[section_read], &src_ptr[buf_offset], section_remain);
555 buf_offset += section_remain;
556 section_read += section_remain;
557 frame_read += section_remain;
558
559 /* finish this read */
560 if((buf_offset >= ETH_RX_BUF_SIZE) || (frame_read >= total))
561 {
562 /* free buffer */
563 rb_descriptors[current_rb_index].addr &= ~(RxDESC_FLAG_OWNSHIP);
564
565 /* move to the next frame. */
566 current_rb_index++;
567 if( current_rb_index >= RB_BUFFER_SIZE ) current_rb_index = 0;
568
569 src_ptr = (rt_uint8_t*)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
570 buf_offset = 0;
571 }
572 }
573 }
574 }
575 }
576
sam7xether_rx(rt_device_t dev)577 struct pbuf *sam7xether_rx(rt_device_t dev)
578 {
579 struct pbuf *p = RT_NULL;
580
581 /* skip fragment frame */
582 while((rb_descriptors[current_rb_index].addr & RxDESC_FLAG_OWNSHIP)
583 && !(rb_descriptors[current_rb_index].status & RxDESC_STATUS_FRAME_START))
584 {
585 rb_descriptors[current_rb_index].addr &= (~RxDESC_FLAG_OWNSHIP);
586
587 current_rb_index++;
588 if(current_rb_index >= RB_BUFFER_SIZE) current_rb_index = 0;
589 }
590
591 if ((rb_descriptors[current_rb_index].addr & RxDESC_FLAG_OWNSHIP))
592 {
593 struct pbuf* q;
594 rt_uint32_t index, pkt_len = 0;
595
596 /* first of all, find the frame length */
597 index = current_rb_index;
598 while (rb_descriptors[index].addr & RxDESC_FLAG_OWNSHIP)
599 {
600 pkt_len = rb_descriptors[index].status & RxDESC_STATUS_BUF_SIZE;
601 if (pkt_len > 0) break;
602
603 index ++;
604 if (index >= RB_BUFFER_SIZE) index = 0;
605 }
606
607 if (pkt_len)
608 {
609 //p = pbuf_alloc(PBUF_LINK, pkt_len, PBUF_RAM);
610 p = pbuf_alloc(PBUF_RAW, pkt_len, PBUF_POOL);
611 if(p != RT_NULL)
612 {
613 sam7xether_read_frame(RT_NULL, 0, pkt_len);
614 for(q = p; q != RT_NULL; q= q->next)
615 sam7xether_read_frame(q->payload, q->len, pkt_len);
616 }
617 else
618 {
619 rt_kprintf("no memory in pbuf\n");
620 }
621 }
622 }
623
624 /* enable interrupt */
625 AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP;
626
627 return p;
628 }
629
sam7xether_register(char * name)630 int sam7xether_register(char *name)
631 {
632 rt_err_t result;
633
634 /* init rt-thread device interface */
635 sam7x_dev_entry.parent.parent.init = sam7xether_init;
636 sam7x_dev_entry.parent.parent.open = sam7xether_open;
637 sam7x_dev_entry.parent.parent.close = sam7xether_close;
638 sam7x_dev_entry.parent.parent.read = sam7xether_read;
639 sam7x_dev_entry.parent.parent.write = sam7xether_write;
640 sam7x_dev_entry.parent.parent.control = sam7xether_control;
641 sam7x_dev_entry.parent.eth_rx = sam7xether_rx;
642 sam7x_dev_entry.parent.eth_tx = sam7xether_tx;
643
644 /* Update MAC address */
645 sam7x_dev_entry.dev_addr[0] = 0x1e;
646 sam7x_dev_entry.dev_addr[1] = 0x30;
647 sam7x_dev_entry.dev_addr[2] = 0x6c;
648 sam7x_dev_entry.dev_addr[3] = 0xa2;
649 sam7x_dev_entry.dev_addr[4] = 0x45;
650 sam7x_dev_entry.dev_addr[5] = 0x5e;
651 /* update mac address */
652 update_mac_address(sam7x_dev);
653
654 rt_sem_init(&tx_sem, "emac", 1, RT_IPC_FLAG_FIFO);
655
656 result = eth_device_init(&(sam7x_dev->parent), (char*)name);
657 RT_ASSERT(result == RT_EOK);
658
659 return RT_EOK;
660 }
661