| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lpc17xx_40xx_emac.c
Go to the documentation of this file.
1 /*
2 * @brief LPC17xx/40xx LWIP EMAC driver
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2012
6 * All rights reserved.
7 *
8 * @par
9 * Software that is described herein is for illustrative purposes only
10 * which provides customers with programming information regarding the
11 * LPC products. This software is supplied "AS IS" without any warranties of
12 * any kind, and NXP Semiconductors and its licensor disclaim any and
13 * all warranties, express or implied, including all implied warranties of
14 * merchantability, fitness for a particular purpose and non-infringement of
15 * intellectual property rights. NXP Semiconductors assumes no responsibility
16 * or liability for the use of the software, conveys no license or rights under any
17 * patent, copyright, mask work right, or any other intellectual property rights in
18 * or to any products. NXP Semiconductors reserves the right to make changes
19 * in the software without notification. NXP Semiconductors also makes no
20 * representation or warranty that such application will be suitable for the
21 * specified use without further testing or modification.
22 *
23 * @par
24 * Permission to use, copy, modify, and distribute this software and its
25 * documentation is hereby granted, under NXP Semiconductors' and its
26 * licensor's relevant copyrights in the software, without fee, provided that it
27 * is used in conjunction with NXP Semiconductors microcontrollers. This
28 * copyright, permission, and disclaimer notice must appear in all copies of
29 * this code.
30 */
31
32 #include "lwip/opt.h"
33 #include "lwip/sys.h"
34 #include "lwip/def.h"
35 #include "lwip/mem.h"
36 #include "lwip/pbuf.h"
37 #include "lwip/stats.h"
38 #include "lwip/snmp.h"
39 #include "netif/etharp.h"
40 #include "netif/ppp_oe.h"
41
42 #include "lpc_17xx40xx_emac_config.h"
43 #include "lpc17xx_40xx_emac.h"
44
45 #include "chip.h"
46 #include "board.h"
47 #include "lpc_phy.h"
48
49 #include <string.h>
50
51 extern void msDelay(uint32_t ms);
52
53 #if LPC_NUM_BUFF_TXDESCS < 2
54 #error LPC_NUM_BUFF_TXDESCS must be at least 2
55 #endif
56
57 #if LPC_NUM_BUFF_RXDESCS < 3
58 #error LPC_NUM_BUFF_RXDESCS must be at least 3
59 #endif
60
65 /*****************************************************************************
66 * Private types/enumerations/variables
67 ****************************************************************************/
68
69 #if NO_SYS == 0
70
76 #define tskRECPKT_PRIORITY (DEFAULT_THREAD_PRIO + 4)
77 #define tskTXCLEAN_PRIORITY (DEFAULT_THREAD_PRIO + 5)
78 // #define tskTXCLEAN_PRIORITY (TCPIP_THREAD_PRIO - 1) // FIXME
79 // #define tskRECPKT_PRIORITY (TCPIP_THREAD_PRIO - 1) // FIXME
80 #endif
81
89 // #define LOCK_RX_THREAD
90
91 #if NO_SYS == 0
92
94 #define RXINTGROUP (ENET_INT_RXOVERRUN | ENET_INT_RXERROR | ENET_INT_RXDONE)
95
98 #define TXINTGROUP (ENET_INT_TXUNDERRUN | ENET_INT_TXERROR | ENET_INT_TXDONE)
99 #else
100 #define RXINTGROUP 0
101 #define TXINTGROUP 0
102 #endif
103
104 /* LPC EMAC driver data structure */
105 typedef struct {
106 /* prxs must be 8 byte aligned! */
107 ENET_RXSTAT_T prxs[LPC_NUM_BUFF_RXDESCS];
108 ENET_RXDESC_T prxd[LPC_NUM_BUFF_RXDESCS];
109 ENET_TXSTAT_T ptxs[LPC_NUM_BUFF_TXDESCS];
110 ENET_TXDESC_T ptxd[LPC_NUM_BUFF_TXDESCS];
111 struct netif *pnetif;
113 struct pbuf *rxb[LPC_NUM_BUFF_RXDESCS];
115 u32_t rx_fill_desc_index;
116 volatile u32_t rx_free_descs;
117 struct pbuf *txb[LPC_NUM_BUFF_TXDESCS];
119 u32_t lpc_last_tx_idx;
120 #if NO_SYS == 0
121 sys_sem_t rx_sem;
122 sys_sem_t tx_clean_sem;
123 sys_mutex_t tx_lock_mutex;
124 sys_mutex_t rx_lock_mutex;
125 xSemaphoreHandle xtx_count_sem;
126 #endif
127 } lpc_enetdata_t;
128
131 ALIGNED(8) lpc_enetdata_t lpc_enetdata;
132
133 /*****************************************************************************
134 * Public types/enumerations/variables
135 ****************************************************************************/
136
137 /*****************************************************************************
138 * Private functions
139 ****************************************************************************/
140
141 /* Queues a pbuf into the RX descriptor list */
142 STATIC void lpc_rxqueue_pbuf(lpc_enetdata_t *lpc_enetif, struct pbuf *p)
143 {
144 u32_t idx;
145
146 /* Get next free descriptor index */
147 idx = lpc_enetif->rx_fill_desc_index;
148
149 /* Setup descriptor and clear statuses */
150 lpc_enetif->prxd[idx].Control = ENET_RCTRL_INT | ((u32_t) ENET_RCTRL_SIZE(p->len));
151 lpc_enetif->prxd[idx].Packet = (u32_t) p->payload;
152 lpc_enetif->prxs[idx].StatusInfo = 0xFFFFFFFF;
153 lpc_enetif->prxs[idx].StatusHashCRC = 0xFFFFFFFF;
154
155 /* Save pbuf pointer for push to network layer later */
156 lpc_enetif->rxb[idx] = p;
157
158 /* Wrap at end of descriptor list */
159 idx++;
160 if (idx >= LPC_NUM_BUFF_RXDESCS) {
161 idx = 0;
162 }
163
164 /* Queue descriptor(s) */
165 lpc_enetif->rx_free_descs -= 1;
166 lpc_enetif->rx_fill_desc_index = idx;
167
168 LWIP_DEBUGF(EMAC_DEBUG | LWIP_DBG_TRACE,
169 ("lpc_rxqueue_pbuf: pbuf packet queued: %p (free desc=%d)\n", p,
170 lpc_enetif->rx_free_descs));
171 }
172
173 /* Sets up the RX descriptor ring buffers. */
174 STATIC err_t lpc_rx_setup(lpc_enetdata_t *lpc_enetif)
175 {
176 /* Setup pointers to RX structures */
177 Chip_ENET_InitRxDescriptors(LPC_ETHERNET, lpc_enetif->prxd, lpc_enetif->prxs, LPC_NUM_BUFF_RXDESCS);
178
179 lpc_enetif->rx_free_descs = LPC_NUM_BUFF_RXDESCS;
180 lpc_enetif->rx_fill_desc_index = 0;
181
182 /* Build RX buffer and descriptors */
183 lpc_rx_queue(lpc_enetif->pnetif);
184
185 return ERR_OK;
186 }
187
188 /* Allocates a pbuf and returns the data from the incoming packet */
189 STATIC struct pbuf *lpc_low_level_input(struct netif *netif) {
190 lpc_enetdata_t *lpc_enetif = netif->state;
191 struct pbuf *p = NULL;
192 u32_t idx, length;
193
194 #ifdef LOCK_RX_THREAD
195 #if NO_SYS == 0
196 /* Get exclusive access */
197 sys_mutex_lock(&lpc_enetif->rx_lock_mutex);
198 #endif
199 #endif
200
201 /* Monitor RX overrun status. This should never happen unless
202 (possibly) the internal bus is behing held up by something.
203 Unless your system is running at a very low clock speed or
204 there are possibilities that the internal buses may be held
205 up for a long time, this can probably safely be removed. */
206 if (Chip_ENET_GetIntStatus(LPC_ETHERNET) & ENET_INT_RXOVERRUN) {
207 LINK_STATS_INC(link.err);
208 LINK_STATS_INC(link.drop);
209
210 /* Temporarily disable RX */
211 Chip_ENET_RXDisable(LPC_ETHERNET);
212
213 /* Reset the RX side */
214 Chip_ENET_ResetRXLogic(LPC_ETHERNET);
215 Chip_ENET_ClearIntStatus(LPC_ETHERNET, ENET_INT_RXOVERRUN);
216
217 /* De-allocate all queued RX pbufs */
218 for (idx = 0; idx < LPC_NUM_BUFF_RXDESCS; idx++) {
219 if (lpc_enetif->rxb[idx] != NULL) {
220 pbuf_free(lpc_enetif->rxb[idx]);
221 lpc_enetif->rxb[idx] = NULL;
222 }
223 }
224
225 /* Start RX side again */
226 lpc_rx_setup(lpc_enetif);
227
228 /* Re-enable RX */
229 Chip_ENET_RXEnable(LPC_ETHERNET);
230
231 #ifdef LOCK_RX_THREAD
232 #if NO_SYS == 0
233 sys_mutex_unlock(&lpc_enetif->rx_lock_mutex);
234 #endif
235 #endif
236
237 return NULL;
238 }
239
240 /* Determine if a frame has been received */
241 length = 0;
242 idx = Chip_ENET_GetRXConsumeIndex(LPC_ETHERNET);
243 if (!Chip_ENET_IsRxEmpty(LPC_ETHERNET)) {
244 /* Handle errors */
245 if (lpc_enetif->prxs[idx].StatusInfo & (ENET_RINFO_CRC_ERR |
246 ENET_RINFO_SYM_ERR | ENET_RINFO_ALIGN_ERR | ENET_RINFO_LEN_ERR)) {
247 #if LINK_STATS
248 if (lpc_enetif->prxs[idx].StatusInfo & (ENET_RINFO_CRC_ERR |
249 ENET_RINFO_SYM_ERR | ENET_RINFO_ALIGN_ERR)) {
250 LINK_STATS_INC(link.chkerr);
251 }
252 if (lpc_enetif->prxs[idx].StatusInfo & ENET_RINFO_LEN_ERR) {
253 LINK_STATS_INC(link.lenerr);
254 }
255 #endif
256
257 /* Drop the frame */
258 LINK_STATS_INC(link.drop);
259
260 /* Re-queue the pbuf for receive */
261 lpc_enetif->rx_free_descs++;
262 p = lpc_enetif->rxb[idx];
263 lpc_enetif->rxb[idx] = NULL;
264 lpc_rxqueue_pbuf(lpc_enetif, p);
265
266 LWIP_DEBUGF(EMAC_DEBUG | LWIP_DBG_TRACE,
267 ("lpc_low_level_input: Packet dropped with errors (0x%x)\n",
268 lpc_enetif->prxs[idx].StatusInfo));
269
270 p = NULL;
271 }
272 else {
273 /* A packet is waiting, get length */
274 length = ENET_RINFO_SIZE(lpc_enetif->prxs[idx].StatusInfo) - 4; /* Remove FCS */
275
276 /* Zero-copy */
277 p = lpc_enetif->rxb[idx];
278 p->len = (u16_t) length;
279
280 /* Free pbuf from desriptor */
281 lpc_enetif->rxb[idx] = NULL;
282 lpc_enetif->rx_free_descs++;
283
284 /* Queue new buffer(s) */
285 if (lpc_rx_queue(lpc_enetif->pnetif) == 0) {
286
287 /* Re-queue the pbuf for receive */
288 lpc_rxqueue_pbuf(lpc_enetif, p);
289
290 /* Drop the frame */
291 LINK_STATS_INC(link.drop);
292
293 LWIP_DEBUGF(EMAC_DEBUG | LWIP_DBG_TRACE,
294 ("lpc_low_level_input: Packet dropped since it could not allocate Rx Buffer\n"));
295
296 p = NULL;
297 }
298 else {
299
300 LWIP_DEBUGF(EMAC_DEBUG | LWIP_DBG_TRACE,
301 ("lpc_low_level_input: Packet received: %p, size %d (index=%d)\n",
302 p, length, idx));
303
304 /* Save size */
305 p->tot_len = (u16_t) length;
306 LINK_STATS_INC(link.recv);
307 }
308 }
309
310 /* Update Consume index */
311 Chip_ENET_IncRXConsumeIndex(LPC_ETHERNET);
312 }
313
314 #ifdef LOCK_RX_THREAD
315 #if NO_SYS == 0
316 sys_mutex_unlock(&lpc_enetif->rx_lock_mutex);
317 #endif
318 #endif
319
320 return p;
321 }
322
323 /* Determine if the passed address is usable for the ethernet DMA controller */
324 STATIC s32_t lpc_packet_addr_notsafe(void *addr) {
325 #if defined(CHIP_LPC175X_6X)
326 /* Check for legal address ranges */
327 if ((((u32_t) addr >= 0x10000000) && ((u32_t) addr < 0x10008000)) /* 32kB local SRAM */
328 || (((u32_t) addr >= 0x1FFF0000) && ((u32_t) addr < 0x1FFF2000)) /* 8kB ROM */
329 || (((u32_t) addr >= 0x2007C000) && ((u32_t) addr < 0x20084000)) /* 32kB AHB SRAM */
330 ) {
331 return 0;
332 }
333 return 1;
334 #else
335 /* Check for legal address ranges */
336 if ((((u32_t) addr >= 0x20000000) && ((u32_t) addr < 0x20008000)) ||
337 (((u32_t) addr >= 0x80000000) && ((u32_t) addr < 0xF0000000))) {
338 return 0;
339 }
340 return 1;
341 #endif
342 }
343
344 /* Sets up the TX descriptor ring buffers */
345 STATIC err_t lpc_tx_setup(lpc_enetdata_t *lpc_enetif)
346 {
347 s32_t idx;
348
349 /* Build TX descriptors for local buffers */
350 for (idx = 0; idx < LPC_NUM_BUFF_TXDESCS; idx++) {
351 lpc_enetif->ptxd[idx].Control = 0;
352 lpc_enetif->ptxs[idx].StatusInfo = 0xFFFFFFFF;
353 }
354
355 /* Setup pointers to TX structures */
356 Chip_ENET_InitTxDescriptors(LPC_ETHERNET, lpc_enetif->ptxd, lpc_enetif->ptxs, LPC_NUM_BUFF_TXDESCS);
357
358 lpc_enetif->lpc_last_tx_idx = 0;
359
360 return ERR_OK;
361 }
362
363 /* Free TX buffers that are complete */
364 STATIC void lpc_tx_reclaim_st(lpc_enetdata_t *lpc_enetif, u32_t cidx)
365 {
366 #if NO_SYS == 0
367 /* Get exclusive access */
368 sys_mutex_lock(&lpc_enetif->tx_lock_mutex);
369 #endif
370
371 while (cidx != lpc_enetif->lpc_last_tx_idx) {
372 if (lpc_enetif->txb[lpc_enetif->lpc_last_tx_idx] != NULL) {
373 LWIP_DEBUGF(EMAC_DEBUG | LWIP_DBG_TRACE,
374 ("lpc_tx_reclaim_st: Freeing packet %p (index %d)\n",
375 lpc_enetif->txb[lpc_enetif->lpc_last_tx_idx],
376 lpc_enetif->lpc_last_tx_idx));
377 pbuf_free(lpc_enetif->txb[lpc_enetif->lpc_last_tx_idx]);
378 lpc_enetif->txb[lpc_enetif->lpc_last_tx_idx] = NULL;
379 }
380
381 #if NO_SYS == 0
382 xSemaphoreGive(lpc_enetif->xtx_count_sem);
383 #endif
384 lpc_enetif->lpc_last_tx_idx++;
385 if (lpc_enetif->lpc_last_tx_idx >= LPC_NUM_BUFF_TXDESCS) {
386 lpc_enetif->lpc_last_tx_idx = 0;
387 }
388 }
389
390 #if NO_SYS == 0
391 /* Restore access */
392 sys_mutex_unlock(&lpc_enetif->tx_lock_mutex);
393 #endif
394 }
395
396 /* Low level output of a packet. Never call this from an interrupt context,
397 * as it may block until TX descriptors become available. */
398 STATIC err_t lpc_low_level_output(struct netif *netif, struct pbuf *p)
399 {
400 lpc_enetdata_t *lpc_enetif = netif->state;
401 struct pbuf *q;
402
403 #if LPC_TX_PBUF_BOUNCE_EN == 1
404 u8_t *dst;
405 struct pbuf *np;
406 #endif
407 u32_t idx;
408 u32_t dn, notdmasafe = 0;
409
410 /* Zero-copy TX buffers may be fragmented across mutliple payload
411 chains. Determine the number of descriptors needed for the
412 transfer. The pbuf chaining can be a mess! */
413 dn = (u32_t) pbuf_clen(p);
414
415 /* Test to make sure packet addresses are DMA safe. A DMA safe
416 address is once that uses external memory or periphheral RAM.
417 IRAM and FLASH are not safe! */
418 for (q = p; q != NULL; q = q->next) {
419 notdmasafe += lpc_packet_addr_notsafe(q->payload);
420 }
421
422 #if LPC_TX_PBUF_BOUNCE_EN == 1
423 /* If the pbuf is not DMA safe, a new bounce buffer (pbuf) will be
424 created that will be used instead. This requires an copy from the
425 non-safe DMA region to the new pbuf */
426 if (notdmasafe) {
427 /* Allocate a pbuf in DMA memory */
428 np = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
429 if (np == NULL) {
430 LWIP_DEBUGF(EMAC_DEBUG | LWIP_DBG_TRACE,
431 ("lpc_low_level_output: could not allocate TX pbuf\n"));
432 return ERR_MEM;
433 }
434
435 /* This buffer better be contiguous! */
436 LWIP_ASSERT("lpc_low_level_output: New transmit pbuf is chained",
437 (pbuf_clen(np) == 1));
438
439 /* Copy to DMA safe pbuf */
440 dst = (u8_t *) np->payload;
441 for (q = p; q != NULL; q = q->next) {
442 /* Copy the buffer to the descriptor's buffer */
443 MEMCPY(dst, (u8_t *) q->payload, q->len);
444 dst += q->len;
445 }
446 np->len = p->tot_len;
447
448 LWIP_DEBUGF(EMAC_DEBUG | LWIP_DBG_TRACE,
449 ("lpc_low_level_output: Switched to DMA safe buffer, old=%p, new=%p\n",
450 q, np));
451
452 /* use the new buffer for descrptor queueing. The original pbuf will
453 be de-allocated outsuide this driver. */
454 p = np;
455 dn = 1;
456 }
457 #else
458 if (notdmasafe) {
459 LWIP_ASSERT("lpc_low_level_output: Not a DMA safe pbuf",
460 (notdmasafe == 0));
461 }
462 #endif
463
464 /* Wait until enough descriptors are available for the transfer. */
465 /* THIS WILL BLOCK UNTIL THERE ARE ENOUGH DESCRIPTORS AVAILABLE */
466 while (dn > lpc_tx_ready(netif)) {
467 #if NO_SYS == 0
468 xSemaphoreTake(lpc_enetif->xtx_count_sem, 0);
469 #else
470 msDelay(1);
471 #endif
472 }
473
474 /* Get free TX buffer index */
475 idx = Chip_ENET_GetTXProduceIndex(LPC_ETHERNET);
476
477 #if NO_SYS == 0
478 /* Get exclusive access */
479 sys_mutex_lock(&lpc_enetif->tx_lock_mutex);
480 #endif
481
482 /* Prevent LWIP from de-allocating this pbuf. The driver will
483 free it once it's been transmitted. */
484 if (!notdmasafe) {
485 pbuf_ref(p);
486 }
487
488 /* Setup transfers */
489 q = p;
490 while (dn > 0) {
491 dn--;
492
493 /* Only save pointer to free on last descriptor */
494 if (dn == 0) {
495 /* Save size of packet and signal it's ready */
496 lpc_enetif->ptxd[idx].Control = ENET_TCTRL_SIZE(q->len) | ENET_TCTRL_INT |
497 ENET_TCTRL_LAST;
498 lpc_enetif->txb[idx] = p;
499 }
500 else {
501 /* Save size of packet, descriptor is not last */
502 lpc_enetif->ptxd[idx].Control = ENET_TCTRL_SIZE(q->len) | ENET_TCTRL_INT;
503 lpc_enetif->txb[idx] = NULL;
504 }
505
506 LWIP_DEBUGF(EMAC_DEBUG | LWIP_DBG_TRACE,
507 ("lpc_low_level_output: pbuf packet(%p) sent, chain#=%d,"
508 " size = %d (index=%d)\n", q->payload, dn, q->len, idx));
509
510 lpc_enetif->ptxd[idx].Packet = (u32_t) q->payload;
511
512 q = q->next;
513
514 idx = Chip_ENET_IncTXProduceIndex(LPC_ETHERNET);
515 }
516
517 LINK_STATS_INC(link.xmit);
518
519 #if NO_SYS == 0
520 /* Restore access */
521 sys_mutex_unlock(&lpc_enetif->tx_lock_mutex);
522 #endif
523
524 return ERR_OK;
525 }
526
527 #if NO_SYS == 0
528 /* Packet reception task for FreeRTOS */
529 STATIC portTASK_FUNCTION(vPacketReceiveTask, pvParameters)
530 {
531 lpc_enetdata_t *lpc_enetif = pvParameters;
532
533 while (1) {
534 /* Wait for receive task to wakeup */
535 sys_arch_sem_wait(&lpc_enetif->rx_sem, 0);
536
537 /* Process packets until all empty */
538 while (!Chip_ENET_IsRxEmpty(LPC_ETHERNET)) {
539 lpc_enetif_input(lpc_enetif->pnetif);
540 }
541 }
542 }
543
544 /* Transmit cleanup task for FreeRTOS */
545 STATIC portTASK_FUNCTION(vTransmitCleanupTask, pvParameters)
546 {
547 lpc_enetdata_t *lpc_enetif = pvParameters;
548 s32_t idx;
549
550 while (1) {
551 /* Wait for transmit cleanup task to wakeup */
552 sys_arch_sem_wait(&lpc_enetif->tx_clean_sem, 0);
553
554 /* Error handling for TX underruns. This should never happen unless
555 something is holding the bus or the clocks are going too slow. It
556 can probably be safely removed. */
557 if (Chip_ENET_GetIntStatus(LPC_ETHERNET) & ENET_INT_TXUNDERRUN) {
558 LINK_STATS_INC(link.err);
559 LINK_STATS_INC(link.drop);
560
561 #if NO_SYS == 0
562 /* Get exclusive access */
563 sys_mutex_lock(&lpc_enetif->tx_lock_mutex);
564 #endif
565 /* Reset the TX side */
566 Chip_ENET_ResetTXLogic(LPC_ETHERNET);
567 Chip_ENET_ClearIntStatus(LPC_ETHERNET, ENET_INT_TXUNDERRUN);
568
569 /* De-allocate all queued TX pbufs */
570 for (idx = 0; idx < LPC_NUM_BUFF_TXDESCS; idx++) {
571 if (lpc_enetif->txb[idx] != NULL) {
572 pbuf_free(lpc_enetif->txb[idx]);
573 lpc_enetif->txb[idx] = NULL;
574 }
575 }
576
577 #if NO_SYS == 0
578 /* Restore access */
579 sys_mutex_unlock(&lpc_enetif->tx_lock_mutex);
580 #endif
581 /* Start TX side again */
582 lpc_tx_setup(lpc_enetif);
583 }
584 else {
585 /* Free TX buffers that are done sending */
586 lpc_tx_reclaim(lpc_enetdata.pnetif);
587 }
588 }
589 }
590
591 #endif
592
593 /* Low level init of the MAC and PHY */
594 STATIC err_t low_level_init(struct netif *netif)
595 {
596 lpc_enetdata_t *lpc_enetif = netif->state;
597 err_t err = ERR_OK;
598
599 Chip_ENET_Init(LPC_ETHERNET);
600
601 /* Initialize the PHY */
602 Chip_ENET_SetupMII(LPC_ETHERNET, Chip_ENET_FindMIIDiv(LPC_ETHERNET, 2500000), LPC_PHYDEF_PHYADDR);
603 #if defined(USE_RMII)
604 if (lpc_phy_init(true, msDelay) != SUCCESS) {
605 return ERROR;
606 }
607 #else
608 if (lpc_phy_init(false, msDelay) != SUCCESS) {
609 return ERROR;
610 }
611 #endif
612
613 /* Save station address */
614 Chip_ENET_SetADDR(LPC_ETHERNET, netif->hwaddr);
615
616 /* Setup transmit and receive descriptors */
617 if (lpc_tx_setup(lpc_enetif) != ERR_OK) {
618 return ERR_BUF;
619 }
620 if (lpc_rx_setup(lpc_enetif) != ERR_OK) {
621 return ERR_BUF;
622 }
623
624 /* Enable packet reception */
625 #if IP_SOF_BROADCAST_RECV
626 Chip_ENET_EnableRXFilter(LPC_ETHERNET, ENET_RXFILTERCTRL_APE | ENET_RXFILTERCTRL_ABE);
627 #else
628 Chip_ENET_EnableRXFilter(ENET_RXFILTERCTRL_APE);
629 #endif
630
631 /* Clear and enable rx/tx interrupts */
632 Chip_ENET_EnableInt(LPC_ETHERNET, RXINTGROUP | TXINTGROUP);
633
634 /* Enable RX and TX */
635 Chip_ENET_TXEnable(LPC_ETHERNET);
636 Chip_ENET_RXEnable(LPC_ETHERNET);
637
638 return err;
639 }
640
641 /* This function is the ethernet packet send function. It calls
642 * etharp_output after checking link status. */
643 STATIC err_t lpc_etharp_output(struct netif *netif, struct pbuf *q,
644 ip_addr_t *ipaddr)
645 {
646 /* Only send packet is link is up */
647 if (netif->flags & NETIF_FLAG_LINK_UP) {
648 return etharp_output(netif, q, ipaddr);
649 }
650
651 return ERR_CONN;
652 }
653
654 /*****************************************************************************
655 * Public functions
656 ****************************************************************************/
657 /* Attempt to allocate and requeue a new pbuf for RX */
658 s32_t lpc_rx_queue(struct netif *netif)
659 {
660 lpc_enetdata_t *lpc_enetif = netif->state;
661 struct pbuf *p;
662
663 s32_t queued = 0;
664
665 /* Attempt to requeue as many packets as possible */
666 while (lpc_enetif->rx_free_descs > 0) {
667 /* Allocate a pbuf from the pool. We need to allocate at the
668 maximum size as we don't know the size of the yet to be
669 received packet. */
670 p = pbuf_alloc(PBUF_RAW, (u16_t) ENET_ETH_MAX_FLEN, PBUF_RAM);
671 if (p == NULL) {
672 LWIP_DEBUGF(EMAC_DEBUG | LWIP_DBG_TRACE,
673 ("lpc_rx_queue: could not allocate RX pbuf (free desc=%d)\n",
674 lpc_enetif->rx_free_descs));
675 return queued;
676 }
677
678 /* pbufs allocated from the RAM pool should be non-chained. */
679 LWIP_ASSERT("lpc_rx_queue: pbuf is not contiguous (chained)",
680 pbuf_clen(p) <= 1);
681
682 /* Queue packet */
683 lpc_rxqueue_pbuf(lpc_enetif, p);
684
685 /* Update queued count */
686 queued++;
687 }
688
689 return queued;
690 }
691
692 /* Attempt to read a packet from the EMAC interface */
693 void lpc_enetif_input(struct netif *netif)
694 {
695 struct eth_hdr *ethhdr;
696
697 struct pbuf *p;
698
699 /* move received packet into a new pbuf */
700 p = lpc_low_level_input(netif);
701 if (p == NULL) {
702 return;
703 }
704
705 /* points to packet payload, which starts with an Ethernet header */
706 ethhdr = p->payload;
707
708 switch (htons(ethhdr->type)) {
709 case ETHTYPE_IP:
710 case ETHTYPE_ARP:
711 #if PPPOE_SUPPORT
712 case ETHTYPE_PPPOEDISC:
713 case ETHTYPE_PPPOE:
714 #endif /* PPPOE_SUPPORT */
715 /* full packet send to tcpip_thread to process */
716 if (netif->input(p, netif) != ERR_OK) {
717 LWIP_DEBUGF(NETIF_DEBUG, ("lpc_enetif_input: IP input error\n"));
718 /* Free buffer */
719 pbuf_free(p);
720 }
721 break;
722
723 default:
724 /* Return buffer */
725 pbuf_free(p);
726 break;
727 }
728 }
729
730 /* Call for freeing TX buffers that are complete */
731 void lpc_tx_reclaim(struct netif *netif)
732 {
733 lpc_tx_reclaim_st((lpc_enetdata_t *) netif->state,
734 Chip_ENET_GetTXConsumeIndex(LPC_ETHERNET));
735 }
736
737 /* Polls if an available TX descriptor is ready */
738 s32_t lpc_tx_ready(struct netif *netif)
739 {
740 u32_t pidx, cidx;
741
742 cidx = Chip_ENET_GetTXConsumeIndex(LPC_ETHERNET);
743 pidx = Chip_ENET_GetTXProduceIndex(LPC_ETHERNET);
744
745 return Chip_ENET_GetFreeDescNum(LPC_ETHERNET, pidx, cidx, LPC_NUM_BUFF_TXDESCS);
746 }
747
754 void ETH_IRQHandler(void)
755 {
756 #if NO_SYS == 1
757 /* Interrupts are not used without an RTOS */
758 NVIC_DisableIRQ(ETHERNET_IRQn);
759 #else
760 signed portBASE_TYPE xRecTaskWoken = pdFALSE, XTXTaskWoken = pdFALSE;
761 uint32_t ints;
762
763 /* Interrupts are of 2 groups - transmit or receive. Based on the
764 interrupt, kick off the receive or transmit (cleanup) task */
765
766 /* Get pending interrupts */
767 ints = Chip_ENET_GetIntStatus(LPC_ETHERNET);
768
769 if (ints & RXINTGROUP) {
770 /* RX group interrupt(s) */
771 /* Give semaphore to wakeup RX receive task. Note the FreeRTOS
772 method is used instead of the LWIP arch method. */
773 xSemaphoreGiveFromISR(lpc_enetdata.rx_sem, &xRecTaskWoken);
774 }
775
776 if (ints & TXINTGROUP) {
777 /* TX group interrupt(s) */
778 /* Give semaphore to wakeup TX cleanup task. Note the FreeRTOS
779 method is used instead of the LWIP arch method. */
780 xSemaphoreGiveFromISR(lpc_enetdata.tx_clean_sem, &XTXTaskWoken);
781 }
782
783 /* Clear pending interrupts */
784 Chip_ENET_ClearIntStatus(LPC_ETHERNET, ints);
785
786 /* Context switch needed? */
787 portEND_SWITCHING_ISR(xRecTaskWoken || XTXTaskWoken);
788 #endif
789 }
790
791 /* Set up the MAC interface duplex */
792 void lpc_emac_set_duplex(int full_duplex)
793 {
794 if (full_duplex) {
795 Chip_ENET_SetFullDuplex(LPC_ETHERNET);
796 }
797 else {
798 Chip_ENET_SetHalfDuplex(LPC_ETHERNET);
799 }
800 }
801
802 /* Set up the MAC interface speed */
803 void lpc_emac_set_speed(int mbs_100)
804 {
805 if (mbs_100) {
806 Chip_ENET_Set100Mbps(LPC_ETHERNET);
807 }
808 else {
809 Chip_ENET_Set10Mbps(LPC_ETHERNET);
810 }
811 }
812
813 /* LWIP 17xx/40xx EMAC initialization function */
814 err_t lpc_enetif_init(struct netif *netif)
815 {
816 err_t err;
817
818 LWIP_ASSERT("netif != NULL", (netif != NULL));
819
820 lpc_enetdata.pnetif = netif;
821
822 /* set MAC hardware address */
823 Board_ENET_GetMacADDR(netif->hwaddr);
824 netif->hwaddr_len = ETHARP_HWADDR_LEN;
825
826 /* maximum transfer unit */
827 netif->mtu = 1500;
828
829 /* device capabilities */
830 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_UP |
831 NETIF_FLAG_ETHERNET;
832
833 /* Initialize the hardware */
834 netif->state = &lpc_enetdata;
835 err = low_level_init(netif);
836 if (err != ERR_OK) {
837 return err;
838 }
839
840 #if LWIP_NETIF_HOSTNAME
841 /* Initialize interface hostname */
842 netif->hostname = "lwiplpc";
843 #endif /* LWIP_NETIF_HOSTNAME */
844
845 netif->name[0] = 'e';
846 netif->name[1] = 'n';
847
848 netif->output = lpc_etharp_output;
849 netif->linkoutput = lpc_low_level_output;
850
851 /* For FreeRTOS, start tasks */
852 #if NO_SYS == 0
853 lpc_enetdata.xtx_count_sem = xSemaphoreCreateCounting(LPC_NUM_BUFF_TXDESCS,
854 LPC_NUM_BUFF_TXDESCS);
855 LWIP_ASSERT("xtx_count_sem creation error",
856 (lpc_enetdata.xtx_count_sem != NULL));
857
858 err = sys_mutex_new(&lpc_enetdata.tx_lock_mutex);
859 LWIP_ASSERT("tx_lock_mutex creation error", (err == ERR_OK));
860
861 err = sys_mutex_new(&lpc_enetdata.rx_lock_mutex);
862 LWIP_ASSERT("rx_lock_mutex creation error", (err == ERR_OK));
863
864 /* Packet receive task */
865 err = sys_sem_new(&lpc_enetdata.rx_sem, 0);
866 LWIP_ASSERT("rx_sem creation error", (err == ERR_OK));
867 sys_thread_new("receive_thread", vPacketReceiveTask, netif->state,
868 DEFAULT_THREAD_STACKSIZE, tskRECPKT_PRIORITY);
869
870 /* Transmit cleanup task */
871 err = sys_sem_new(&lpc_enetdata.tx_clean_sem, 0);
872 LWIP_ASSERT("tx_clean_sem creation error", (err == ERR_OK));
873 sys_thread_new("txclean_thread", vTransmitCleanupTask, netif->state,
874 DEFAULT_THREAD_STACKSIZE, tskTXCLEAN_PRIORITY);
875 #endif
876
877 return ERR_OK;
878 }
879