LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 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! */
111  struct netif *pnetif;
113  struct pbuf *rxb[LPC_NUM_BUFF_RXDESCS];
116  volatile u32_t rx_free_descs;
117  struct pbuf *txb[LPC_NUM_BUFF_TXDESCS];
120 #if NO_SYS == 0
125  xSemaphoreHandle xtx_count_sem;
126 #endif
128 
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. */
175 {
176  /* Setup pointers to RX structures */
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. */
207  LINK_STATS_INC(link.err);
208  LINK_STATS_INC(link.drop);
209 
210  /* Temporarily disable RX */
212 
213  /* Reset the RX side */
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 */
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;
244  /* Handle errors */
245  if (lpc_enetif->prxs[idx].StatusInfo & (ENET_RINFO_CRC_ERR |
247 #if LINK_STATS
248  if (lpc_enetif->prxs[idx].StatusInfo & (ENET_RINFO_CRC_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 */
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 */
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 */
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 */
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 */
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 |
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 
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 */
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. */
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 */
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 */
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 
600 
601  /* Initialize the PHY */
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
627 #else
629 #endif
630 
631  /* Clear and enable rx/tx interrupts */
633 
634  /* Enable RX and TX */
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,
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 
744 
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 */
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 */
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) {
796  }
797  else {
799  }
800 }
801 
802 /* Set up the MAC interface speed */
803 void lpc_emac_set_speed(int mbs_100)
804 {
805  if (mbs_100) {
807  }
808  else {
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,
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,
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,
875 #endif
876 
877  return ERR_OK;
878 }
879