diff --git a/arch/arm/src/kinetis/Make.defs b/arch/arm/src/kinetis/Make.defs
index 2b48320ff4a04f3e57a4e0971b28c4a7ca08af76..913ed182cfd98a1d54afaad75db1c3224c75e21b 100644
--- a/arch/arm/src/kinetis/Make.defs
+++ b/arch/arm/src/kinetis/Make.defs
@@ -49,7 +49,7 @@ CMN_CSRCS	= up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \
 		  up_doirq.c up_hardfault.c up_svcall.c up_checkstack.c
 
 ifeq ($(CONFIG_NET),y)
-ifneq ($(CONFIG_KINETIS_ETHERNET),y)
+ifneq ($(CONFIG_KINETIS_ENET),y)
 CMN_CSRCS	+= up_etherstub.c
 endif
 endif
@@ -88,7 +88,7 @@ CHIP_CSRCS	+= kinetis_dma.c
 endif
 
 ifeq ($(CONFIG_NET),y)
-ifeq ($(CONFIG_KINETIS_ETHERNET),y)
+ifeq ($(CONFIG_KINETIS_ENET),y)
 CHIP_CSRCS	+= kinetis_enet.c
 endif
 endif
diff --git a/arch/arm/src/kinetis/chip.h b/arch/arm/src/kinetis/chip.h
index cb4ae4de376fef19b0503264fef505308d9cf333..253562a06ec07cdadbe274d5388b2f391a53c83d 100644
--- a/arch/arm/src/kinetis/chip.h
+++ b/arch/arm/src/kinetis/chip.h
@@ -836,6 +836,7 @@
 #define NVIC_SYSH_PRIORITY_MIN     0xf0 /* All bits[7:4] set is minimum priority */
 #define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */
 #define NVIC_SYSH_PRIORITY_MAX     0x00 /* Zero is maximum priority */
+#define NVIC_SYSH_PRIORITY_STEP    0x10 /* Steps between supported priority values */
 
 /************************************************************************************
  * Public Types
diff --git a/arch/arm/src/kinetis/kinetis_config.h b/arch/arm/src/kinetis/kinetis_config.h
index b4f72224452bb8ed01819df536ef3f4f41567e2e..80ceb3f30197006bf77a0366897c10c4788f9a08 100644
--- a/arch/arm/src/kinetis/kinetis_config.h
+++ b/arch/arm/src/kinetis/kinetis_config.h
@@ -1,203 +1,224 @@
-/************************************************************************************
- * arch/arm/src/kinetis/kinetis_config.h
- *
- *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ************************************************************************************/
-
-#ifndef __ARCH_ARM_SRC_KINETISXX_KINETIS_CONFIG_H
-#define __ARCH_ARM_SRC_KINETISXX_KINETIS_CONFIG_H
-
-/************************************************************************************
- * Included Files
- ************************************************************************************/
-
-#include <nuttx/config.h>
-#include <arch/board/board.h>
-
-#include "chip.h"
-
-/************************************************************************************
- * Pre-processor Definitions
- ************************************************************************************/
-
-/* Configuration *********************************************************************/
-/* Make that no unsupport UARTs are enabled */
-
-#ifndef KINETIS_NISO7816
-#  define KINETIS_NISO7816 0
-#endif
-
-#if (KINETIS_NISO7816 + KINETIS_NUART) < 6
-#  undef CONFIG_KINETIS_UART5
-#  if (KINETIS_NISO7816 + KINETIS_NUART) < 5
-#    undef CONFIG_KINETIS_UART4
-#    if (KINETIS_NISO7816 + KINETIS_NUART) < 4
-#      undef CONFIG_KINETIS_UART3
-#      if (KINETIS_NISO7816 + KINETIS_NUART) < 3
-#        undef CONFIG_KINETIS_UART2
-#        if (KINETIS_NISO7816 + KINETIS_NUART) < 2
-#          undef CONFIG_KINETIS_UART1
-#          if (KINETIS_NISO7816 + KINETIS_NUART) < 1
-#            undef CONFIG_KINETIS_UART0
-#          endif
-#        endif
-#      endif
-#    endif
-#  endif
-#endif
-
-/* Are any UARTs enabled? */
-
-#undef HAVE_UART_DEVICE
-#if defined(CONFIG_KINETIS_UART0) || defined(CONFIG_KINETIS_UART1) || \
-    defined(CONFIG_KINETIS_UART2) || defined(CONFIG_KINETIS_UART3) || \
-    defined(CONFIG_KINETIS_UART5)
-#  define HAVE_UART_DEVICE 1
-#endif
-
-/* Is there a serial console? There should be at most one defined.  It could be on
- * any UARTn, n=0,1,2,3,4,5
- */
-
-#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART0)
-#  undef CONFIG_UART1_SERIAL_CONSOLE
-#  undef CONFIG_UART2_SERIAL_CONSOLE
-#  undef CONFIG_UART3_SERIAL_CONSOLE
-#  undef CONFIG_UART4_SERIAL_CONSOLE
-#  undef CONFIG_UART5_SERIAL_CONSOLE
-#  define HAVE_SERIAL_CONSOLE 1
-#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART1)
-#  undef CONFIG_UART0_SERIAL_CONSOLE
-#  undef CONFIG_UART2_SERIAL_CONSOLE
-#  undef CONFIG_UART3_SERIAL_CONSOLE
-#  undef CONFIG_UART4_SERIAL_CONSOLE
-#  undef CONFIG_UART5_SERIAL_CONSOLE
-#  define HAVE_SERIAL_CONSOLE 1
-#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART2)
-#  undef CONFIG_UART0_SERIAL_CONSOLE
-#  undef CONFIG_UART1_SERIAL_CONSOLE
-#  undef CONFIG_UART3_SERIAL_CONSOLE
-#  undef CONFIG_UART4_SERIAL_CONSOLE
-#  undef CONFIG_UART5_SERIAL_CONSOLE
-#  define HAVE_SERIAL_CONSOLE 1
-#elif defined(CONFIG_UART3_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART3)
-#  undef CONFIG_UART0_SERIAL_CONSOLE
-#  undef CONFIG_UART1_SERIAL_CONSOLE
-#  undef CONFIG_UART2_SERIAL_CONSOLE
-#  undef CONFIG_UART4_SERIAL_CONSOLE
-#  undef CONFIG_UART5_SERIAL_CONSOLE
-#  define HAVE_SERIAL_CONSOLE 1
-#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART4)
-#  undef CONFIG_UART0_SERIAL_CONSOLE
-#  undef CONFIG_UART1_SERIAL_CONSOLE
-#  undef CONFIG_UART2_SERIAL_CONSOLE
-#  undef CONFIG_UART3_SERIAL_CONSOLE
-#  undef CONFIG_UART5_SERIAL_CONSOLE
-#  define HAVE_SERIAL_CONSOLE 1
-#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART5)
-#  undef CONFIG_UART0_SERIAL_CONSOLE
-#  undef CONFIG_UART1_SERIAL_CONSOLE
-#  undef CONFIG_UART2_SERIAL_CONSOLE
-#  undef CONFIG_UART3_SERIAL_CONSOLE
-#  undef CONFIG_UART4_SERIAL_CONSOLE
-#  define HAVE_SERIAL_CONSOLE 1
-#else
-#  undef CONFIG_UART0_SERIAL_CONSOLE
-#  undef CONFIG_UART1_SERIAL_CONSOLE
-#  undef CONFIG_UART2_SERIAL_CONSOLE
-#  undef CONFIG_UART3_SERIAL_CONSOLE
-#  undef CONFIG_UART4_SERIAL_CONSOLE
-#  undef CONFIG_UART5_SERIAL_CONSOLE
-#  undef HAVE_SERIAL_CONSOLE
-#endif
-
-/* Check UART flow control (Not yet supported) */
-
-# undef CONFIG_UART0_FLOWCONTROL
-# undef CONFIG_UART1_FLOWCONTROL
-# undef CONFIG_UART2_FLOWCONTROL
-# undef CONFIG_UART3_FLOWCONTROL
-# undef CONFIG_UART4_FLOWCONTROL
-# undef CONFIG_UART5_FLOWCONTROL
-
-/* UART FIFO support is not fully implemented.
- *
- * NOTE:  UART0 has an 8-byte deep FIFO; the other UARTs have no FIFOs
- * (1-deep).  There appears to be no way to know when the FIFO is not
- * full (other than reading the FIFO length and comparing the FIFO count).
- * Hence, the FIFOs are not used in this implementation and, as a result
- * TDRE indeed mean that the single output buffer is available.
- *
- * Performance on UART0 could be improved by enabling the FIFO and by
- * redesigning all of the FIFO status logic.
- */
-
-#undef CONFIG_KINETIS_UARTFIFOS
-
-/* Default Priorities */
-
-#ifndef CONFIG_KINETIS_UART0PRIO
-#  define CONFIG_KINETIS_UART0PRIO NVIC_SYSH_PRIORITY_DEFAULT
-#endif
-#ifndef CONFIG_KINETIS_UART1PRIO
-#  define CONFIG_KINETIS_UART1PRIO NVIC_SYSH_PRIORITY_DEFAULT
-#endif
-#ifndef CONFIG_KINETIS_UART2PRIO
-#  define CONFIG_KINETIS_UART2PRIO NVIC_SYSH_PRIORITY_DEFAULT
-#endif
-#ifndef CONFIG_KINETIS_UART3PRIO
-#  define CONFIG_KINETIS_UART3PRIO NVIC_SYSH_PRIORITY_DEFAULT
-#endif
-#ifndef CONFIG_KINETIS_UART4PRIO
-#  define CONFIG_KINETIS_UART4PRIO NVIC_SYSH_PRIORITY_DEFAULT
-#endif
-#ifndef CONFIG_KINETIS_UART5PRIO
-#  define CONFIG_KINETIS_UART5PRIO NVIC_SYSH_PRIORITY_DEFAULT
-#endif
-
-/************************************************************************************
- * Public Types
- ************************************************************************************/
-
-/************************************************************************************
- * Public Data
- ************************************************************************************/
-
-/************************************************************************************
- * Inline Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Public Functions
- ************************************************************************************/
-
-#endif /* __ARCH_ARM_SRC_KINETISXX_KINETIS_CONFIG_H */
+/************************************************************************************
+ * arch/arm/src/kinetis/kinetis_config.h
+ *
+ *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_KINETISXX_KINETIS_CONFIG_H
+#define __ARCH_ARM_SRC_KINETISXX_KINETIS_CONFIG_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include <nuttx/config.h>
+#include <arch/board/board.h>
+
+#include "chip.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Configuration *********************************************************************/
+/* Make that no unsupport UARTs are enabled */
+
+#ifndef KINETIS_NISO7816
+#  define KINETIS_NISO7816 0
+#endif
+
+#if (KINETIS_NISO7816 + KINETIS_NUART) < 6
+#  undef CONFIG_KINETIS_UART5
+#  if (KINETIS_NISO7816 + KINETIS_NUART) < 5
+#    undef CONFIG_KINETIS_UART4
+#    if (KINETIS_NISO7816 + KINETIS_NUART) < 4
+#      undef CONFIG_KINETIS_UART3
+#      if (KINETIS_NISO7816 + KINETIS_NUART) < 3
+#        undef CONFIG_KINETIS_UART2
+#        if (KINETIS_NISO7816 + KINETIS_NUART) < 2
+#          undef CONFIG_KINETIS_UART1
+#          if (KINETIS_NISO7816 + KINETIS_NUART) < 1
+#            undef CONFIG_KINETIS_UART0
+#          endif
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* Are any UARTs enabled? */
+
+#undef HAVE_UART_DEVICE
+#if defined(CONFIG_KINETIS_UART0) || defined(CONFIG_KINETIS_UART1) || \
+    defined(CONFIG_KINETIS_UART2) || defined(CONFIG_KINETIS_UART3) || \
+    defined(CONFIG_KINETIS_UART5)
+#  define HAVE_UART_DEVICE 1
+#endif
+
+/* Is there a serial console? There should be at most one defined.  It could be on
+ * any UARTn, n=0,1,2,3,4,5
+ */
+
+#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART0)
+#  undef CONFIG_UART1_SERIAL_CONSOLE
+#  undef CONFIG_UART2_SERIAL_CONSOLE
+#  undef CONFIG_UART3_SERIAL_CONSOLE
+#  undef CONFIG_UART4_SERIAL_CONSOLE
+#  undef CONFIG_UART5_SERIAL_CONSOLE
+#  define HAVE_SERIAL_CONSOLE 1
+#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART1)
+#  undef CONFIG_UART0_SERIAL_CONSOLE
+#  undef CONFIG_UART2_SERIAL_CONSOLE
+#  undef CONFIG_UART3_SERIAL_CONSOLE
+#  undef CONFIG_UART4_SERIAL_CONSOLE
+#  undef CONFIG_UART5_SERIAL_CONSOLE
+#  define HAVE_SERIAL_CONSOLE 1
+#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART2)
+#  undef CONFIG_UART0_SERIAL_CONSOLE
+#  undef CONFIG_UART1_SERIAL_CONSOLE
+#  undef CONFIG_UART3_SERIAL_CONSOLE
+#  undef CONFIG_UART4_SERIAL_CONSOLE
+#  undef CONFIG_UART5_SERIAL_CONSOLE
+#  define HAVE_SERIAL_CONSOLE 1
+#elif defined(CONFIG_UART3_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART3)
+#  undef CONFIG_UART0_SERIAL_CONSOLE
+#  undef CONFIG_UART1_SERIAL_CONSOLE
+#  undef CONFIG_UART2_SERIAL_CONSOLE
+#  undef CONFIG_UART4_SERIAL_CONSOLE
+#  undef CONFIG_UART5_SERIAL_CONSOLE
+#  define HAVE_SERIAL_CONSOLE 1
+#elif defined(CONFIG_UART4_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART4)
+#  undef CONFIG_UART0_SERIAL_CONSOLE
+#  undef CONFIG_UART1_SERIAL_CONSOLE
+#  undef CONFIG_UART2_SERIAL_CONSOLE
+#  undef CONFIG_UART3_SERIAL_CONSOLE
+#  undef CONFIG_UART5_SERIAL_CONSOLE
+#  define HAVE_SERIAL_CONSOLE 1
+#elif defined(CONFIG_UART5_SERIAL_CONSOLE) && defined(CONFIG_KINETIS_UART5)
+#  undef CONFIG_UART0_SERIAL_CONSOLE
+#  undef CONFIG_UART1_SERIAL_CONSOLE
+#  undef CONFIG_UART2_SERIAL_CONSOLE
+#  undef CONFIG_UART3_SERIAL_CONSOLE
+#  undef CONFIG_UART4_SERIAL_CONSOLE
+#  define HAVE_SERIAL_CONSOLE 1
+#else
+#  undef CONFIG_UART0_SERIAL_CONSOLE
+#  undef CONFIG_UART1_SERIAL_CONSOLE
+#  undef CONFIG_UART2_SERIAL_CONSOLE
+#  undef CONFIG_UART3_SERIAL_CONSOLE
+#  undef CONFIG_UART4_SERIAL_CONSOLE
+#  undef CONFIG_UART5_SERIAL_CONSOLE
+#  undef HAVE_SERIAL_CONSOLE
+#endif
+
+/* Check UART flow control (Not yet supported) */
+
+# undef CONFIG_UART0_FLOWCONTROL
+# undef CONFIG_UART1_FLOWCONTROL
+# undef CONFIG_UART2_FLOWCONTROL
+# undef CONFIG_UART3_FLOWCONTROL
+# undef CONFIG_UART4_FLOWCONTROL
+# undef CONFIG_UART5_FLOWCONTROL
+
+/* UART FIFO support is not fully implemented.
+ *
+ * NOTE:  UART0 has an 8-byte deep FIFO; the other UARTs have no FIFOs
+ * (1-deep).  There appears to be no way to know when the FIFO is not
+ * full (other than reading the FIFO length and comparing the FIFO count).
+ * Hence, the FIFOs are not used in this implementation and, as a result
+ * TDRE indeed mean that the single output buffer is available.
+ *
+ * Performance on UART0 could be improved by enabling the FIFO and by
+ * redesigning all of the FIFO status logic.
+ */
+
+#undef CONFIG_KINETIS_UARTFIFOS
+
+/* UART Default Interrupt Priorities */
+
+#ifndef CONFIG_KINETIS_UART0PRIO
+#  define CONFIG_KINETIS_UART0PRIO NVIC_SYSH_PRIORITY_DEFAULT
+#endif
+#ifndef CONFIG_KINETIS_UART1PRIO
+#  define CONFIG_KINETIS_UART1PRIO NVIC_SYSH_PRIORITY_DEFAULT
+#endif
+#ifndef CONFIG_KINETIS_UART2PRIO
+#  define CONFIG_KINETIS_UART2PRIO NVIC_SYSH_PRIORITY_DEFAULT
+#endif
+#ifndef CONFIG_KINETIS_UART3PRIO
+#  define CONFIG_KINETIS_UART3PRIO NVIC_SYSH_PRIORITY_DEFAULT
+#endif
+#ifndef CONFIG_KINETIS_UART4PRIO
+#  define CONFIG_KINETIS_UART4PRIO NVIC_SYSH_PRIORITY_DEFAULT
+#endif
+#ifndef CONFIG_KINETIS_UART5PRIO
+#  define CONFIG_KINETIS_UART5PRIO NVIC_SYSH_PRIORITY_DEFAULT
+#endif
+
+/* Ethernet controller configuration */
+
+#ifndef CONFIG_ENET_NBUFFERS
+#  define CONFIG_ENET_NBUFFERS 8
+#endif
+
+/* EMAC Default Interrupt Priorities */
+
+#ifndef CONFIG_KINETIS_EMACTMR_PRIO
+#  define CONFIG_KINETIS_EMACTMR_PRIO  NVIC_SYSH_PRIORITY_DEFAULT
+#endif
+#ifndef CONFIG_KINETIS_EMACTX_PRIO
+#  define CONFIG_KINETIS_EMACTX_PRIO   NVIC_SYSH_PRIORITY_DEFAULT
+#endif
+#ifndef CONFIG_KINETIS_EMACRX_PRIO
+#  define CONFIG_KINETIS_EMACRX_PRIO   NVIC_SYSH_PRIORITY_DEFAULT
+#endif
+#ifndef CONFIG_KINETIS_EMACMISC_PRIO
+#  define CONFIG_KINETIS_EMACMISC_PRIO NVIC_SYSH_PRIORITY_DEFAULT
+#endif
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Inline Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_KINETISXX_KINETIS_CONFIG_H */
diff --git a/arch/arm/src/kinetis/kinetis_enet.c b/arch/arm/src/kinetis/kinetis_enet.c
new file mode 100644
index 0000000000000000000000000000000000000000..6b8a90b06a656461823874c1867911a57ec186fc
--- /dev/null
+++ b/arch/arm/src/kinetis/kinetis_enet.c
@@ -0,0 +1,1302 @@
+/****************************************************************************
+ * drivers/net/kinetis_enet.c
+ *
+ *   Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#if defined(CONFIG_NET) && defined(CONFIG_KINETIS_ENET)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <time.h>
+#include <string.h>
+#include <debug.h>
+#include <wdog.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+
+#include <net/uip/uip.h>
+#include <net/uip/uip-arp.h>
+#include <net/uip/uip-arch.h>
+
+#include "chip.h"
+#include "kinetis_sim.h"
+#include "kinetis_mpu.h"
+#include "kinetis_enet.h"
+
+#if defined(KINETIS_NENET) && KINETIS_NENET > 0
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* CONFIG_KINETIS_NETHIFS determines the number of physical interfaces
+ * that will be supported.
+ */
+
+#ifndef CONFIG_KINETIS_NETHIFS
+# define CONFIG_KINETIS_NETHIFS 1
+#endif
+
+#ifdef CONFIG_ENET_LEGACYDESC
+#  error "Legacy descriptor types are not supported"
+#endif
+
+/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per second */
+
+#define KINETIS_WDDELAY   (1*CLK_TCK)
+#define KINETIS_POLLHSEC  (1*2)
+
+/* TX timeout = 1 minute */
+
+#define KINETIS_TXTIMEOUT (60*CLK_TCK)
+#define MII_TIMEOUT       (0x1ffff)
+
+/* Estimate the hold time to use based on the peripheral (bus) clock.
+ * BUS_FREQ = 48Mhz, hold time clocks = (2*48)/5 + 1 = 19.
+ */
+
+#define KINETIS_MII_SPEED ((2*BOARD_BUS_FREQ)/5 + 1)
+#if KINETIS_MII_SPEED > 63
+#  error "KINETIS_MII_SPEED is out-of-range"
+#endif
+
+/* This is a helper pointer for accessing the contents of the Ethernet header */
+
+#define BUF ((struct uip_eth_hdr *)priv->dev.d_buf)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* The kinetis_driver_s encapsulates all state information for a single hardware
+ * interface
+ */
+
+struct kinetis_driver_s
+{
+  bool bifup;                    /* true:ifup false:ifdown */
+  uint8_t nextdesc;              /* The next descriptor to use */
+  WDOG_ID txpoll;                /* TX poll timer */
+  WDOG_ID txtimeout;             /* TX timeout timer */
+  struct enet_desc_s *g_txdesc;  /* A pointer to the (single) TX descriptor */
+  struct enet_desc_s *priv->rxdesc;  /* A pointer the list of RX descriptors */
+
+  /* This holds the information visible to uIP/NuttX */
+
+  struct uip_driver_s dev;  /* Interface understood by uIP */
+
+  /* The DMA descriptors.  A unaligned uint8_t is used to allocate the
+   * memory; 16 is added to assure that we can meet the desciptor alignment
+   * requirements; 1 is added for the single TX descriptor.
+   */
+
+ uint8_t desc[((CONFIG_ENET_NTXBUFFERS+1) * sizeof(struct enet_desc_s)) + 16];
+
+  /* The DMA buffers.  Again, A unaligned uint8_t is used to allocate the
+   * memory; 16 is added to assure that we can meet the desciptor alignment
+   * requirements.
+   */
+
+  uint8_t rxbuffers[(CONFIG_ENET_NTXBUFFERS * CONFIG_NET_BUFSIZE) + 16];
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct kinetis_driver_s g_enet[CONFIG_KINETIS_NETHIFS];
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+/* Utility functions */
+
+#ifdef CONFIG_ENDIAN_BIG
+#  define kinesis_swap32(value) (value)
+#  define kinesis_swap16(value) (value)
+#else
+static inline uint32_t kinesis_swap32(uint32_t value);
+static inline __asm int32_t kinesis_swap16(int16_t value);
+#endif
+
+/* Common TX logic */
+
+static int  kinetis_transmit(FAR struct kinetis_driver_s *priv);
+static int  kinetis_uiptxpoll(struct uip_driver_s *dev);
+
+/* Interrupt handling */
+
+static void kinetis_receive(FAR struct kinetis_driver_s *priv);
+static void kinetis_txdone(FAR struct kinetis_driver_s *priv);
+static int  kinetis_interrupt(int irq, FAR void *context);
+#if 0
+static int  kinetis_tmrinterrupt(int irq, FAR void *context);
+#endif
+static int  kinetis_txrinterrupt(int irq, FAR void *context);
+static int  kinetis_rxrinterrupt(int irq, FAR void *context);
+static int  kinetis_miscinterrupt(int irq, FAR void *context);
+
+/* Watchdog timer expirations */
+
+static void kinetis_polltimer(int argc, uint32_t arg, ...);
+static void kinetis_txtimeout(int argc, uint32_t arg, ...);
+
+/* NuttX callback functions */
+
+static int kinetis_ifup(struct uip_driver_s *dev);
+static int kinetis_ifdown(struct uip_driver_s *dev);
+static int kinetis_txavail(struct uip_driver_s *dev);
+#ifdef CONFIG_NET_IGMP
+static int kinetis_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
+static int kinetis_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
+#endif
+
+/* PHY/MII support */
+
+static inline void kinetis_initmii(struct kinetis_driver_s *priv);
+static inline void kinetis_initphy(struct kinetis_driver_s *priv);
+
+/* Initialization */
+
+static void kinetis_initbuffers(struct kinetis_driver_s *priv);
+static void kinetis_reset(struct kinetis_driver_s *priv);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: kinetis_swap16/32
+ *
+ * Description:
+ *   The descriptors are represented by structures  Unfortunately, when the
+ *   structures are overlayed on the data, the bytes are reversed because
+ *   the underlying hardware writes the data in big-endian byte order.
+ *
+ * Parameters:
+ *   value  - The value to be byte swapped
+ *
+ * Returned Value:
+ *   The byte swapped value
+ *
+ ****************************************************************************/
+
+#ifndef CONFIG_ENDIAN_BIG
+static inline uint32_t kinesis_swap32(uint32_t value)
+{
+  uint32_t result = 0;
+
+  __asm volatile ("rev %0, %1":"=r" (result): "r"(value));
+  return result;
+}
+
+static inline __asm int32_t kinesis_swap16(int16_t value)
+{
+  revsh r0, r0 bx lr
+}
+#endif
+
+/****************************************************************************
+ * Function: kinetis_transmit
+ *
+ * Description:
+ *   Start hardware transmission.  Called either from the txdone interrupt
+ *   handling or from watchdog based polling.
+ *
+ * Parameters:
+ *   priv  - Reference to the driver state structure
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ *   May or may not be called from an interrupt handler.  In either case,
+ *   global interrupts are disabled, either explicitly or indirectly through
+ *   interrupt handling logic.
+ *
+ ****************************************************************************/
+
+static int kinetis_transmit(FAR struct kinetis_driver_s *priv)
+{
+  /* Verify that the hardware is ready to send another packet.  If we get
+   * here, then we are committed to sending a packet; Higher level logic
+   * must have assured that there is not transmission in progress.
+   */
+
+  /* Increment statistics */
+
+  /* Send the packet: address=priv->dev.d_buf, length=priv->dev.d_len */
+#warning "Missing logic"
+
+  /* Enable Tx interrupts */
+
+  /* Setup the TX timeout watchdog (perhaps restarting the timer) */
+
+  (void)wd_start(priv->txtimeout, KINETIS_TXTIMEOUT, kinetis_txtimeout, 1, (uint32_t)priv);
+  return OK;
+}
+
+/****************************************************************************
+ * Function: kinetis_uiptxpoll
+ *
+ * Description:
+ *   The transmitter is available, check if uIP has any outgoing packets ready
+ *   to send.  This is a callback from uip_poll().  uip_poll() may be called:
+ *
+ *   1. When the preceding TX packet send is complete,
+ *   2. When the preceding TX packet send timesout and the interface is reset
+ *   3. During normal TX polling
+ *
+ * Parameters:
+ *   dev  - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ *   May or may not be called from an interrupt handler.  In either case,
+ *   global interrupts are disabled, either explicitly or indirectly through
+ *   interrupt handling logic.
+ *
+ ****************************************************************************/
+
+static int kinetis_uiptxpoll(struct uip_driver_s *dev)
+{
+  FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)dev->d_private;
+
+  /* If the polling resulted in data that should be sent out on the network,
+   * the field d_len is set to a value > 0.
+   */
+
+  if (priv->dev.d_len > 0)
+    {
+      uip_arp_out(&priv->dev);
+      kinetis_transmit(priv);
+
+      /* Check if there is room in the device to hold another packet. If not,
+       * return a non-zero value to terminate the poll.
+       */
+#warning "Missing logic"
+    }
+
+  /* If zero is returned, the polling will continue until all connections have
+   * been examined.
+   */
+
+  return 0;
+}
+
+/****************************************************************************
+ * Function: kinetis_receive
+ *
+ * Description:
+ *   An interrupt was received indicating the availability of a new RX packet
+ *
+ * Parameters:
+ *   priv  - Reference to the driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Global interrupts are disabled by interrupt handling logic.
+ *
+ ****************************************************************************/
+
+static void kinetis_receive(FAR struct kinetis_driver_s *priv)
+{
+  do
+    {
+      /* Check for errors and update statistics */
+
+      /* Check if the packet is a valid size for the uIP buffer configuration */
+
+      /* Copy the data data from the hardware to priv->dev.d_buf.  Set
+       * amount of data in priv->dev.d_len
+       */
+#warning "Missing logic"
+
+      /* We only accept IP packets of the configured type and ARP packets */
+
+#ifdef CONFIG_NET_IPv6
+      if (BUF->type == HTONS(UIP_ETHTYPE_IP6))
+#else
+      if (BUF->type == HTONS(UIP_ETHTYPE_IP))
+#endif
+        {
+          uip_arp_ipin(&priv->dev);
+          uip_input(&priv->dev);
+
+          /* If the above function invocation resulted in data that should be
+           * sent out on the network, the field  d_len will set to a value > 0.
+           */
+
+          if (priv->dev.d_len > 0)
+           {
+             uip_arp_out(&priv->dev);
+             kinetis_transmit(priv);
+           }
+        }
+      else if (BUF->type == htons(UIP_ETHTYPE_ARP))
+        {
+          uip_arp_arpin(&priv->dev);
+
+          /* If the above function invocation resulted in data that should be
+           * sent out on the network, the field  d_len will set to a value > 0.
+           */
+
+          if (priv->dev.d_len > 0)
+            {
+              kinetis_transmit(priv);
+            }
+        }
+    }
+  while (); /* While there are more packets to be processed */
+}
+
+/****************************************************************************
+ * Function: kinetis_txdone
+ *
+ * Description:
+ *   An interrupt was received indicating that the last TX packet(s) is done
+ *
+ * Parameters:
+ *   priv  - Reference to the driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Global interrupts are disabled by the watchdog logic.
+ *
+ ****************************************************************************/
+
+static void kinetis_txdone(FAR struct kinetis_driver_s *priv)
+{
+  /* Check for errors and update statistics */
+
+  /* If no further xmits are pending, then cancel the TX timeout and
+   * disable further Tx interrupts.
+   */
+
+  wd_cancel(priv->txtimeout);
+
+  /* Then poll uIP for new XMIT data */
+
+  (void)uip_poll(&priv->dev, kinetis_uiptxpoll);
+}
+
+/****************************************************************************
+ * Function: kinetis_tmrinterrupt
+ *
+ * Description:
+ *   Ethernet MAC IEEE 1588 timer interrupt handler
+ *
+ * Parameters:
+ *   irq     - Number of the IRQ that generated the interrupt
+ *   context - Interrupt register state save info (architecture-specific)
+ *
+ * Returned Value:
+ *   OK on success
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+#if 0
+static int kinetis_tmrinterrupt(int irq, FAR void *context)
+{
+  register FAR struct kinetis_driver_s *priv = &g_enet[0];
+
+  /* Get and clear interrupt status bits */
+
+  /* Handle interrupts according to status bit settings */
+#warning "Missing logic"
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Function: kinetis_txinterrupt
+ *
+ * Description:
+ *   Ethernet MAC transmit interrupt handler
+ *
+ * Parameters:
+ *   irq     - Number of the IRQ that generated the interrupt
+ *   context - Interrupt register state save info (architecture-specific)
+ *
+ * Returned Value:
+ *   OK on success
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int kinetis_txinterrupt(int irq, FAR void *context)
+{
+  register FAR struct kinetis_driver_s *priv = &g_enet[0];
+
+  /* Get and clear interrupt status bits */
+
+  /* Handle interrupts according to status bit settings */
+#warning "Missing logic"
+
+  /* Check if a packet transmission just completed.  If so, call kinetis_txdone.
+   * This may disable further Tx interrupts if there are no pending
+   * tansmissions.
+   */
+
+  kinetis_txdone(priv);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Function: kinetis_rxinterrupt
+ *
+ * Description:
+ *   Hardware interrupt handler
+ *
+ * Parameters:
+ *   irq     - Number of the IRQ that generated the interrupt
+ *   context - Interrupt register state save info (architecture-specific)
+ *
+ * Returned Value:
+ *   OK on success
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int kinetis_rxinterrupt(int irq, FAR void *context)
+{
+  register FAR struct kinetis_driver_s *priv = &g_enet[0];
+
+  /* Get and clear interrupt status bits */
+
+  /* Handle interrupts according to status bit settings */
+#warning "Missing logic"
+
+  /* Check if we received an incoming packet, if so, call kinetis_receive() */
+
+  kinetis_receive(priv);
+  return OK;
+}
+
+/****************************************************************************
+ * Function: kinetis_miscinterrupt
+ *
+ * Description:
+ *   Ethernet MAC error and misc interrupt handler
+ *
+ * Parameters:
+ *   irq     - Number of the IRQ that generated the interrupt
+ *   context - Interrupt register state save info (architecture-specific)
+ *
+ * Returned Value:
+ *   OK on success
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int kinetis_miscinterrupt(int irq, FAR void *context)
+{
+  register FAR struct kinetis_driver_s *priv = &g_enet[0];
+
+  /* Get and clear interrupt status bits */
+
+  /* Handle interrupts according to status bit settings */
+#warning "Missing logic"
+
+  return OK;
+}
+
+/****************************************************************************
+ * Function: kinetis_txtimeout
+ *
+ * Description:
+ *   Our TX watchdog timed out.  Called from the timer interrupt handler.
+ *   The last TX never completed.  Reset the hardware and start again.
+ *
+ * Parameters:
+ *   argc - The number of available arguments
+ *   arg  - The first argument
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Global interrupts are disabled by the watchdog logic.
+ *
+ ****************************************************************************/
+
+static void kinetis_txtimeout(int argc, uint32_t arg, ...)
+{
+  FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
+
+  /* Increment statistics and dump debug info */
+
+  /* Then reset the hardware */
+#warning "Missing logic"
+
+  /* Then poll uIP for new XMIT data */
+
+  (void)uip_poll(&priv->dev, kinetis_uiptxpoll);
+}
+
+/****************************************************************************
+ * Function: kinetis_polltimer
+ *
+ * Description:
+ *   Periodic timer handler.  Called from the timer interrupt handler.
+ *
+ * Parameters:
+ *   argc - The number of available arguments
+ *   arg  - The first argument
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Global interrupts are disabled by the watchdog logic.
+ *
+ ****************************************************************************/
+
+static void kinetis_polltimer(int argc, uint32_t arg, ...)
+{
+  FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
+
+  /* Check if there is room in the send another TX packet.  We cannot perform
+   * the TX poll if he are unable to accept another packet for transmission.
+   */
+#warning "Missing logic"
+
+  /* If so, update TCP timing states and poll uIP for new XMIT data. Hmmm..
+   * might be bug here.  Does this mean if there is a transmit in progress,
+   * we will missing TCP time state updates?
+   */
+
+  (void)uip_timer(&priv->dev, kinetis_uiptxpoll, KINETIS_POLLHSEC);
+
+  /* Setup the watchdog poll timer again */
+
+  (void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer, 1, arg);
+}
+
+/****************************************************************************
+ * Function: kinetis_ifup
+ *
+ * Description:
+ *   NuttX Callback: Bring up the Ethernet interface when an IP address is
+ *   provided 
+ *
+ * Parameters:
+ *   dev  - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int kinetis_ifup(struct uip_driver_s *dev)
+{
+  FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)dev->d_private;
+
+  ndbg("Bringing up: %d.%d.%d.%d\n",
+       dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
+       (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 );
+
+  /* Initialize PHYs, the Ethernet interface, and setup up Ethernet interrupts */
+#warning "Missing logic"
+
+  /* Set and activate a timer process */
+
+  (void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer, 1, (uint32_t)priv);
+
+  /* Enable the Ethernet interrupts */
+
+  priv->bifup = true;
+#if 0
+  up_enable_irq(KINETIS_IRQ_EMACTMR);
+#endif
+  up_enable_irq(KINETIS_IRQ_EMACTX);
+  up_enable_irq(KINETIS_IRQ_EMACRX);
+  up_enable_irq(KINETIS_IRQ_EMACMISC);
+  return OK;
+}
+
+/****************************************************************************
+ * Function: kinetis_ifdown
+ *
+ * Description:
+ *   NuttX Callback: Stop the interface.
+ *
+ * Parameters:
+ *   dev  - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int kinetis_ifdown(struct uip_driver_s *dev)
+{
+  FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)dev->d_private;
+  irqstate_t flags;
+
+  /* Disable the Ethernet interrupt */
+
+  flags = irqsave();
+  up_disable_irq(KINETIS_IRQ_EMACTMR);
+  up_disable_irq(KINETIS_IRQ_EMACTX);
+  up_disable_irq(KINETIS_IRQ_EMACRX);
+  up_disable_irq(KINETIS_IRQ_EMACMISC);
+
+  /* Cancel the TX poll timer and TX timeout timers */
+
+  wd_cancel(priv->txpoll);
+  wd_cancel(priv->txtimeout);
+
+  /* Put the EMAC in its reset, non-operational state.  This should be
+   * a known configuration that will guarantee the kinetis_ifup() always
+   * successfully brings the interface back up.
+   */
+#warning "Missing logic"
+
+  /* Mark the device "down" */
+
+  priv->bifup = false;
+  irqrestore(flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Function: kinetis_txavail
+ *
+ * Description:
+ *   Driver callback invoked when new TX data is available.  This is a 
+ *   stimulus perform an out-of-cycle poll and, thereby, reduce the TX
+ *   latency.
+ *
+ * Parameters:
+ *   dev  - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Called in normal user mode
+ *
+ ****************************************************************************/
+
+static int kinetis_txavail(struct uip_driver_s *dev)
+{
+  FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)dev->d_private;
+  irqstate_t flags;
+
+  /* Disable interrupts because this function may be called from interrupt
+   * level processing.
+   */
+
+  flags = irqsave();
+
+  /* Ignore the notification if the interface is not yet up */
+
+  if (priv->bifup)
+    {
+      /* Check if there is room in the hardware to hold another outgoing packet. */
+
+      /* If so, then poll uIP for new XMIT data */
+
+      (void)uip_poll(&priv->dev, kinetis_uiptxpoll);
+    }
+
+  irqrestore(flags);
+  return OK;
+}
+
+/****************************************************************************
+ * Function: kinetis_addmac
+ *
+ * Description:
+ *   NuttX Callback: Add the specified MAC address to the hardware multicast
+ *   address filtering
+ *
+ * Parameters:
+ *   dev  - Reference to the NuttX driver state structure
+ *   mac  - The MAC address to be added 
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IGMP
+static int kinetis_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
+{
+  FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)dev->d_private;
+
+  /* Add the MAC address to the hardware multicast routing table */
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Function: kinetis_rmmac
+ *
+ * Description:
+ *   NuttX Callback: Remove the specified MAC address from the hardware multicast
+ *   address filtering
+ *
+ * Parameters:
+ *   dev  - Reference to the NuttX driver state structure
+ *   mac  - The MAC address to be removed 
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_IGMP
+static int kinetis_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
+{
+  FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)dev->d_private;
+
+  /* Add the MAC address to the hardware multicast routing table */
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Function: kinetis_initmii
+ *
+ * Description:
+ *   Configure the MII interface
+ *
+ * Parameters:
+ *   priv - Reference to the private ENET driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void kinetis_initmii(struct kinetis_driver_s *priv)
+{
+  /* Speed is based on the peripheral (bus) clock; hold time is 1 module
+   * clock.  This hold time value may need to be increased on some platforms
+   */
+
+  putreg32(ENET_MSCR_HOLDTIME_1CYCLE |
+           KINETIS_MII_SPEED << ENET_MSCR_MII_SPEED_SHIFT,
+           KINETIS_ENET_MSCR);
+}
+
+/****************************************************************************
+ * Function: kinetis_writemii
+ *
+ * Description:
+ *   Write a 16-bit value to a PHY register. 
+ *
+ * Parameters:
+ *   priv - Reference to the private ENET driver state structure
+ *   phyaddr - The PHY address
+ *   regaddr - The PHY register address
+ *   data    - The data to write to the PHY register
+ *
+ * Returned Value:
+ *   Zero on success, a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int kinetis_writemii(struct kinetis_driver_s *priv, uint8_t phyaddr,
+                            uint8_t regaddr, uint16_t data)
+{
+  int timeout;
+
+  /* Clear the MII interrupt bit */
+
+  putreg32(ENET_INT_MII, KINETIS_ENET_EIR);
+
+  /* Initiatate the MII Management write */
+
+  putreg32(data |
+           2 << ENET_MMFR_TA_SHIFT |
+           (uint32_t)regaddr << ENET_MMFR_PA_SHIFT |
+           (uint32_t)phyaddr << ENET_MMFR_PA_SHIFT |
+           ENET_MMFR_OP_WRMII |
+           1 << ENET_MMFR_ST_SHIFT,
+           KINETIS_ENET_MMFR);
+
+  /* Wait for the transfer to complete */
+
+  for (timeout = 0; timeout < MII_TIMEOUT; timeout++)
+    {
+      if ((getreg32(KINETIS_ENET_EIR) & ENET_INT_MII) != 0)
+        {
+          break;
+        }
+    }
+
+  /* Check for a timeout */
+
+  if(timeout == MII_TIMEOUT) 
+    {
+      return -ETIMEDOUT;
+    }
+
+  /* Clear the MII interrupt bit */
+
+  putreg32(ENET_INT_MII, KINETIS_ENET_EIR);
+  return OK;
+}
+
+/****************************************************************************
+ * Function: kinetis_writemii
+ *
+ * Description:
+ *   Read a 16-bit value from a PHY register. 
+ *
+ * Parameters:
+ *   priv    - Reference to the private ENET driver state structure
+ *   phyaddr - The PHY address
+ *   regaddr - The PHY register address
+ *   data    - A pointer to the location to return the data
+ *
+ * Returned Value:
+ *   Zero on success, a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int kinetis_readmii(struct kinetis_driver_s *priv, uint8_t phyaddr,
+                           uint8_t regaddr, uint16_t *data)
+{
+  int timeout;
+
+  /* Clear the MII interrupt bit */
+
+  putreg32(ENET_INT_MII, KINETIS_ENET_EIR);
+
+  /* Initiatate the MII Management read */
+ 
+  putreg32(2 << ENET_MMFR_TA_SHIFT |
+           (uint32_t)regaddr << ENET_MMFR_PA_SHIFT |
+           (uint32_t)phyaddr << ENET_MMFR_PA_SHIFT |
+           ENET_MMFR_OP_RDMII |
+           1 << ENET_MMFR_ST_SHIFT,
+           KINETIS_ENET_MMFR);
+
+  /* Wait for the transfer to complete */
+
+  for (timeout = 0; timeout < MII_TIMEOUT; timeout++)
+    {
+      if ((getreg32(KINETIS_ENET_EIR) & ENET_INT_MII) != 0)
+        {
+          break;
+        }
+    }
+
+  /* Check for a timeout */
+
+  if(timeout == MII_TIMEOUT) 
+    {
+      return -ETIMEDOUT;
+    }
+
+  /* Clear the MII interrupt bit */
+
+  putreg32(ENET_INT_MII, KINETIS_ENET_EIR);
+
+  /* And return the MII data */
+
+  *data = (uint16_t)(getreg32(KINETIS_ENET_MMFR) & ENET_MMFR_DATA_MASK));
+  return OK;
+}
+
+/****************************************************************************
+ * Function: kinetis_initphy
+ *
+ * Description:
+ *   Configure the PHY
+ *
+ * Parameters:
+ *   priv - Reference to the private ENET driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static inline void kinetis_initphy(struct kinetis_driver_s *priv)
+{
+#warning "Missing logic"
+}
+
+/****************************************************************************
+ * Function: kinetis_initbuffers
+ *
+ * Description:
+ *   Initialize ENET buffers and descriptors
+ *
+ * Parameters:
+ *   priv - Reference to the private ENET driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void kinetis_initbuffers(struct kinetis_driver_s *priv)
+{
+  uintptr_t addr;
+  uint8_t *desc;
+  int i;
+
+  /* Get an aligned TX descriptor address */
+
+  addr     = (uintptr_t)priv->desc + 0x0f) & ~0x0f;
+  g_txdesc = (struct enet_desc_s *)addr;
+
+  /* Get an aligned RX descriptor (array) address */
+
+  addr    +=  sizeof(struct enet_desc_s);
+  g_txdesc = (struct enet_desc_s *)addr;
+
+  /* There is no TX buffer (the RX buffer is reused). */
+
+  g_txdesc->length  = 0;
+  g_txdesc->status1 = TXDESC_W;
+#ifdef CONFIG_ENET_ENHANCEDBD
+  g_txdesc->status2 = TXDESC_IINS | TXDESC_PINS;
+#endif
+
+  /* Get the beginning of the first aligned RX buffer */
+
+  addr = ((uintptr_t)priv->rxbuffers + 0x0f) & ~0x0f;
+
+  /* Then fill in the Rx descriptors */
+
+  for (i = 0; i < CONFIG_ENET_NTXBUFFERS; i++)
+    {
+      priv->rxdesc[i].status1 = RXDESC_E;
+      priv->rxdesc[i].length  = 0;
+      priv->rxdesc[i].data    = (uint8_t*)kinesis_swap32((uint32_t)addr);
+#ifdef CONFIG_ENET_ENHANCEDBD
+      priv->rxdesc[i].bdu     = 0x00000000;
+      priv->rxdesc[i].status2 = RXDESC_INT;
+#endif
+      addr                   += CONFIG_NET_BUFSIZE;
+    }
+
+  /* Set the wrap bit in the last descriptors to form a ring */
+
+  priv->rxdesc[CONFIG_ENET_NTXBUFFERS - 1].status1 |= RXDESC_W;
+
+  /* We start with descriptor 0 */
+
+  priv->nextdesc = 0;
+}
+
+/****************************************************************************
+ * Function: kinetis_reset
+ *
+ * Description:
+ *   Put the EMAC in the non-operational, reset state
+ *
+ * Parameters:
+ *   priv - Reference to the private ENET driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void kinetis_reset(struct kinetis_driver_s *priv)
+{
+  unsigned int i;
+
+  /* Set the reset bit and clear the enable bit */
+
+  putreg32(ENET_ECR_RESET, KINETIS_ENET_ECR);
+
+  /* Wait at least 8 clock cycles */
+
+  for (i = 0; i < 10; i++)
+    {
+      asm volatile ("nop");
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: kinetis_initialize
+ *
+ * Description:
+ *   Initialize the Ethernet controller and driver
+ *
+ * Parameters:
+ *   intf - In the case where there are multiple EMACs, this value
+ *          identifies which EMAC is to be initialized.
+ *
+ * Returned Value:
+ *   OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int kinetis_initialize(int intf)
+{
+  struct kinetis_driver_s *priv;
+  uint32_t regval;
+
+  /* Get the interface structure associated with this interface number. */
+
+  DEBUGASSERT(inf < CONFIG_KINETIS_NETHIFS);
+  priv = &g_enet[intf];
+
+  /* Enable the ENET clock */
+
+  regval  = getreg32(KINETIS_SIM_SCGC2);
+  regval |= SIM_SCGC2_ENET
+  putreg32(regval, KINETIS_SIM_SCGC2);
+
+  /* Allow concurrent access to MPU controller. Example: ENET uDMA to SRAM,
+   * otherwise a bus error will result.
+   */
+
+  putreg32(0, KINETIS_MPU_CESR);
+
+  /* Initialize ENET buffer */
+
+  kinetis_initbuffers(priv);
+
+  /* Reset and disable the interface */
+
+  kinetis_reset(priv);
+
+  /* Configure the MII interface */
+
+  kinetis_initmii(priv);
+
+  /* Configure all ENET/MII pins */
+
+#if CONFIG_ENET_USEMII
+  kinetis_pinconfig(PIN_MII0_MDIO);
+  kinetis_pinconfig(PIN_MII0_MDC);
+  kinetis_pinconfig(PIN_MII0_RXDV);
+  kinetis_pinconfig(PIN_MII0_RXER);
+  kinetis_pinconfig(PIN_MII0_TXER);
+  kinetis_pinconfig(PIN_MII0_RXD0);
+  kinetis_pinconfig(PIN_MII0_RXD1);
+  kinetis_pinconfig(PIN_MII0_RXD2);
+  kinetis_pinconfig(PIN_MII0_RXD3);
+  kinetis_pinconfig(PIN_MII0_TXD0);
+  kinetis_pinconfig(PIN_MII0_TXD1);
+  kinetis_pinconfig(PIN_MII0_TXD3);
+  kinetis_pinconfig(PIN_MII0_TXD2);
+  kinetis_pinconfig(PIN_MII0_TXEN);
+  kinetis_pinconfig(PIN_MII0_RXCLK);
+  kinetis_pinconfig(PIN_MII0_TXCLK);
+  kinetis_pinconfig(PIN_MII0_CRS);
+  kinetis_pinconfig(PIN_MII0_COL);
+#else
+  kinetis_pinconfig(PIN_RMII0_MDIO);
+  kinetis_pinconfig(PIN_RMII0_MDC);
+  kinetis_pinconfig(PIN_RMII0_CRS_DV);
+  kinetis_pinconfig(PIN_RMII0_RXER);
+  kinetis_pinconfig(PIN_RMII0_RXD0);
+  kinetis_pinconfig(PIN_RMII0_RXD1);
+  kinetis_pinconfig(PIN_RMII0_TXD0);
+  kinetis_pinconfig(PIN_RMII0_TXD1);
+  kinetis_pinconfig(PIN_RMII0_TXEN);
+#endif   
+
+  /* Set interrupt priority levels */
+
+  up_prioritize_irq(KINETIS_IRQ_EMACTMR, CONFIG_KINETIS_EMACTMR_PRIO);
+  up_prioritize_irq(KINETIS_IRQ_EMACTX, CONFIG_KINETIS_EMACTX_PRIO);
+  up_prioritize_irq(KINETIS_IRQ_EMACRX, CONFIG_KINETIS_EMACRX_PRIO);
+  up_prioritize_irq(KINETIS_IRQ_EMACMISC, CONFIG_KINETIS_EMACMISC_PRIO);
+
+  /* Attach the Ethernet MAC IEEE 1588 timer interrupt handler */
+
+#if 0
+  if (irq_attach(KINETIS_IRQ_EMACTMR, kinetis_tmrinterrupt))
+    {
+      /* We could not attach the ISR to the interrupt */
+
+      return -EAGAIN;
+    }
+#endif
+
+  /* Attach the Ethernet MAC transmit interrupt handler */
+
+  if (irq_attach(KINETIS_IRQ_EMACTX, kinetis_txinterrupt))
+    {
+      /* We could not attach the ISR to the interrupt */
+
+      return -EAGAIN;
+    }
+
+  /* Attach the Ethernet MAC receive interrupt handler */
+
+  if (irq_attach(KINETIS_IRQ_EMACRX, kinetis_rxinterrupt))
+    {
+      /* We could not attach the ISR to the interrupt */
+
+      return -EAGAIN;
+    }
+
+  /* Attach the Ethernet MAC error and misc interrupt handler */
+
+  if (irq_attach(KINETIS_IRQ_EMACMISC, kinetis_miscinterrupt))
+    {
+      /* We could not attach the ISR to the interrupt */
+
+      return -EAGAIN;
+    }
+
+  /* Configure the PHY */
+
+  kinetis_initphy(priv);
+
+  /* Handle promiscuous mode */
+
+#ifdef CONFIG_NET_PROMISCUOUS
+  regval = getreg32(KINETIS_ENET_RCR);
+  regval |= ENET_RCR_PROM;
+  putreg32(regval, KINETIS_ENET_RCR);
+#endif
+
+  /* Select legacy of enhanced buffer descriptor format */
+
+#ifdef CONFIG_ENET_ENHANCEDBD
+  putreg32(ENET_ECR_EN1588, KINETIS_ENET_ECR);
+#else
+  putreg32(0, KINETIS_ENET_ECR);
+#endif
+
+  /* Set the RX buffer size */
+
+  putreg32(CONFIG_NET_BUFSIZE, KINETIS_ENET_MRBR);
+
+  /* Point to the start of the circular RX buffer descriptor queue */
+
+  putreg32((uint32_t)priv->rxdesc, KINETIS_ENET_RDSR);
+
+  /* Point to the single TX buffer descriptor */
+
+  putreg32((uint32_t)priv->txdesc, KINETIS_ENET_TDSR);
+
+  /* Indicate that there have been empty receive buffers produced */
+
+  putreg32(ENET_RDAR, KINETIS_ENET_RDAR);
+
+  /* Initialize the driver structure */
+
+  memset(priv, 0, sizeof(struct kinetis_driver_s));
+  priv->dev.d_ifup    = kinetis_ifup;     /* I/F up (new IP address) callback */
+  priv->dev.d_ifdown  = kinetis_ifdown;   /* I/F down callback */
+  priv->dev.d_txavail = kinetis_txavail;  /* New TX data callback */
+#ifdef CONFIG_NET_IGMP
+  priv->dev.d_addmac  = kinetis_addmac;   /* Add multicast MAC address */
+  priv->dev.d_rmmac   = kinetis_rmmac;    /* Remove multicast MAC address */
+#endif
+  priv->dev.d_private = (void*)g_enet; /* Used to recover private state from dev */
+
+  /* Create a watchdog for timing polling for and timing of transmisstions */
+
+  priv->txpoll       = wd_create();   /* Create periodic poll timer */
+  priv->txtimeout    = wd_create();   /* Create TX timeout timer */
+
+  /* Clear all pending ENET interrupt */
+
+  putreg32(0xffffffff, KINETIS_ENET_EIR);
+
+  /* Enable interrupts (interrupts are still disabled at the NVIC). */
+
+  putreg32(ENET_INT_BABR  | ENET_INT_TXF | ENET_INT_RXF | ENET_INT_RXB |
+           ENET_INT_EBERR | ENET_INT_LC  | ENET_INT_RL  |  ENET_INT_UN,
+           KINETIS_ENET_EIMR);
+
+  /* And enable the MAC itself */
+
+  regval = getreg32(KINETIS_ENET_ECR);
+  regval |= ENET_ECR_ETHEREN;
+  putreg32(regval, KINETIS_ENET_ECR);
+
+  /* Put the interface in the down state.  This usually amounts to resetting
+   * the device and/or calling kinetis_ifdown().
+   */
+
+  (void)kinetis_ifdown(&priv->dev);
+
+  /* Register the device with the OS so that socket IOCTLs can be performed */
+
+  (void)netdev_register(&priv->dev);
+  return OK;
+}
+
+#endif /* KINETIS_NENET > 0 */
+#endif /* CONFIG_NET && CONFIG_KINETIS_ENET */
diff --git a/arch/arm/src/kinetis/kinetis_enet.h b/arch/arm/src/kinetis/kinetis_enet.h
index 793866800b1f218a891fedc0795a423041ca6fe1..91b8ff70e8dd8e104b1658eda7c4085c66b02124 100644
--- a/arch/arm/src/kinetis/kinetis_enet.h
+++ b/arch/arm/src/kinetis/kinetis_enet.h
@@ -433,9 +433,171 @@
                                                /* Bits 8-31: Reserved */
 /* Timer Compare Capture Register (32-bit compare value) */
 
+/* Buffer Descriptors ***********************************************************************/
+/* Endian-independent descriptor offsets */
+
+#define DESC_STATUS1_OFFSET         (0)
+#define DESC_LENGTH_OFFSET          (2)
+#define DESC_DATAPTR_OFFSET         (4)
+#define DESC_LEGACY_LEN             (8)
+
+#define DESC_STATUS2_OFFSET         (8)
+#define DESC_LENPROTO_OFFSET        (12)
+#define DESC_CHECKSUM_OFFSET        (14)
+#define DESC_BDU_OFFSET             (16)
+#define DESC_TIMESTAMP_OFFSET       (20)
+#define DESC_ENHANCED_LEN           (32)
+
+/* Legacy/Common TX Buffer Descriptor Bit Definitions.
+ *
+ *   The descriptors are represented by structures  Unfortunately, when the
+ *   structures are overlayed on the data, the bytes are reversed because
+ *   the underlying hardware writes the data in big-endian byte order.
+ */
+
+#ifdef CONFIG_ENDIAN_BIG
+#  define TXDESC_ABC                 (1 << 9)  /* Legacy */
+#  define TXDESC_TC                  (1 << 10) /* Common */
+#  define TXDESC_L                   (1 << 11) /* Common */
+#  define TXDESC_TO2                 (1 << 12) /* Common */
+#  define TXDESC_W                   (1 << 13) /* Common */
+#  define TXDESC_TO1                 (1 << 14) /* Common */
+#  define TXDESC_R                   (1 << 15) /* Common */
+#endif
+#  define TXDESC_ABC                 (1 << 1)  /* Legacy */
+#  define TXDESC_TC                  (1 << 2)  /* Common */
+#  define TXDESC_L                   (1 << 3)  /* Common */
+#  define TXDESC_TO2                 (1 << 4)  /* Common */
+#  define TXDESC_W                   (1 << 5)  /* Common */
+#  define TXDESC_TO1                 (1 << 6)  /* Common */
+#  define TXDESC_R                   (1 << 7)  /* Common */
+#endif
+
+/* Enhanced (only) TX Buffer Descriptor Bit Definitions */
+
+#ifdef CONFIG_ENDIAN_BIG
+#  define TXDESC_TSE                 (1 << 8)
+#  define TXDESC_OE                  (1 << 9) 
+#  define TXDESC_LCE                 (1 << 10) 
+#  define TXDESC_FE                  (1 << 11) 
+#  define TXDESC_EE                  (1 << 12)
+#  define TXDESC_UE                  (1 << 13)
+#  define TXDESC_TXE                 (1 << 15)
+
+#  define TXDESC_IINS                (1 << 27)
+#  define TXDESC_PINS                (1 << 28)
+#  define TXDESC_TS                  (1 << 29)
+#  define TXDESC_INT                 (1 << 30)
+
+#  define TXDESC_BDU                 (1 << 31)
+
+#else
+#  define TXDESC_IINS                (1 << 3)
+#  define TXDESC_PINS                (1 << 4)
+#  define TXDESC_TS                  (1 << 5)
+#  define TXDESC_INT                 (1 << 6)
+
+#  define TXDESC_TSE                 (1 << 16) 
+#  define TXDESC_OE                  (1 << 17) 
+#  define TXDESC_LCE                 (1 << 18) 
+#  define TXDESC_FE                  (1 << 19) 
+#  define TXDESC_EE                  (1 << 20)
+#  define TXDESC_UE                  (1 << 21)
+#  define TXDESC_TXE                 (1 << 23)
+
+#  define TXDESC_BDU                 (1 << 7)    
+#endif
+
+/* Legacy (and Common) RX Buffer Descriptor Bit Definitions */
+
+#ifdef CONFIG_ENDIAN_BIG
+#  define RXDESC_TR                  (1 << 0)
+#  define RXDESC_OV                  (1 << 1)
+#  define RXDESC_CR                  (1 << 2)
+#  define RXDESC_NO                  (1 << 4)
+#  define RXDESC_LG                  (1 << 5)
+#  define RXDESC_MC                  (1 << 6)
+#  define RXDESC_BC                  (1 << 7)
+#  define RXDESC_M                   (1 << 8)
+#  define RXDESC_L                   (1 << 11)
+#  define RXDESC_R02                 (1 << 12)
+#  define RXDESC_W                   (1 << 13)
+#  define RXDESC_R01                 (1 << 14)
+#  define RXDESC_E                   (1 << 15)
+#else
+#  define RXDESC_M                   (1 << 0)
+#  define RXDESC_L                   (1 << 3)
+#  define RXDESC_R02                 (1 << 4)
+#  define RXDESC_W                   (1 << 5)
+#  define RXDESC_R01                 (1 << 6)
+#  define RXDESC_E                   (1 << 7)
+#  define RXDESC_TR                  (1 << 8)
+#  define RXDESC_OV                  (1 << 9)
+#  define RXDESC_CR                  (1 << 10)
+#  define RXDESC_NO                  (1 << 12)
+#  define RXDESC_LG                  (1 << 13)
+#  define RXDESC_MC                  (1 << 14)
+#  define RXDESC_BC                  (1 << 15)
+#endif
+
+/* Enhanced (only) TX Buffer Descriptor Bit Definitions */
+
+#ifdef CONFIG_ENDIAN_BIG
+#  define RXDESC_FRAG                (1 << 0)
+#  define RXDESC_IPV6                (1 << 1)
+#  define RXDESC_VLAN                (1 << 2)
+#  define RXDESC_PCR                 (1 << 4)
+#  define RXDESC_ICE                 (1 << 5)
+#  define RXDESC_INT                 (1 << 23)
+#  define RXDESC_UC                  (1 << 24)
+#  define RXDESC_CE                  (1 << 25)
+#  define RXDESC_PE                  (1 << 26)
+#  define RXDESC_ME                  (1 << 31)
+
+#  define RXDESC_BDU                 (1 << 31)    
+#else
+#  define RXDESC_UC                  (1 << 0)
+#  define RXDESC_CE                  (1 << 1)
+#  define RXDESC_PE                  (1 << 2)
+#  define RXDESC_ME                  (1 << 7)
+#  define RXDESC_INT                 (1 << 15)
+#  define RXDESC_FRAG                (1 << 24)
+#  define RXDESC_IPV6                (1 << 25)
+#  define RXDESC_VLAN                (1 << 26)
+#  define RXDESC_PCR                 (1 << 28)
+#  define RXDESC_ICE                 (1 << 29)
+
+#  define RXDESC_BDU                 (1 << 7)
+#endif
+
 /********************************************************************************************
  * Public Types
  ********************************************************************************************/
+/* Buffer Descriptors ***********************************************************************/
+/* Legacy Buffer Descriptor */
+
+#ifdef CONFIG_ENET_ENHANCEDBD
+struct enet_desc_s
+{
+  uint16_t status1;     /* Control and status */
+  uint16_t length;      /* Data length */
+  uint8_t  *data;       /* Buffer address */
+  uint32_t status2;     /* Extended status */
+  uint16_t lenproto;    /* Header length + Protocol type */
+  uint16_t checksum;    /* Payload checksum */
+  uint32_t bdu;         /* BDU */
+  uint32_t timestamp;   /* Time stamp */
+  uint32_t reserved1;   /* unused */
+  uint32_t reserved2;   /* unused */
+}
+#else
+struct enet_desc_s
+{
+  uint16_t status1;     /* Control and status */
+  uint16_t length;      /* Data length */
+  uint8_t  *data;       /* Buffer address */
+};
+#endif
 
 /********************************************************************************************
  * Public Data
diff --git a/arch/arm/src/kinetis/kinetis_k60pinmux.h b/arch/arm/src/kinetis/kinetis_k60pinmux.h
index f65c8dff145f304c21ea99cfb23b7b01fb858400..dee0d15d67aea5c975c23da4f28eb5ef5664d27e 100644
--- a/arch/arm/src/kinetis/kinetis_k60pinmux.h
+++ b/arch/arm/src/kinetis/kinetis_k60pinmux.h
@@ -82,8 +82,13 @@
 #define PIN_FTM0_CH1_1           (PIN_ALT3   | PIN_PORTA | PIN4)
 #define PIN_NMI                  (PIN_ALT7   | PIN_PORTA | PIN4)
 #define PIN_FTM0_CH2_1           (PIN_ALT3   | PIN_PORTA | PIN5)
-#define PIN_RMII0_RXER           (PIN_ALT4   | PIN_PORTA | PIN5)
-#define PIN_MII0_RXER            (PIN_ALT4   | PIN_PORTA | PIN5)
+#if 0
+#  define PIN_RMII0_RXER         (PIN_ALT4   | PIN_PORTA | PIN5)
+#  define PIN_MII0_RXER          (PIN_ALT4   | PIN_PORTA | PIN5)
+#else
+#  define PIN_RMII0_RXER         (GPIO_PULLDOWN | PIN_PORTA | PIN5)
+# define PIN_MII0_RXER           (GPIO_PULLDOWN | PIN_PORTA | PIN5)
+#endif
 #define PIN_CMP2_OUT_1           (PIN_ALT5   | PIN_PORTA | PIN5)
 #define PIN_I2S0_RX_BCLK_1       (PIN_ALT6   | PIN_PORTA | PIN5)
 #define PIN_JTAG_TRST            (PIN_ALT7   | PIN_PORTA | PIN5)
diff --git a/arch/arm/src/kinetis/kinetis_sim.h b/arch/arm/src/kinetis/kinetis_sim.h
index 2086f24cd52360d1893658ae31edf52ca4f6e16d..399ed8d515859993c2c0868d8292f68274ff7330 100644
--- a/arch/arm/src/kinetis/kinetis_sim.h
+++ b/arch/arm/src/kinetis/kinetis_sim.h
@@ -292,7 +292,7 @@
                                                 /* Bits 12-31: Reserved */
 /* System Clock Gating Control Register 2 */
 
-#ifdef KINETIS_K60
+#if defined(KINETIS_NENET) && KINETIS_NENET > 0
 #  define SIM_SCGC2_ENET              (1 << 0)  /* Bit 0:  ENET Clock Gate Control (K60) */
 #endif
                                                 /* Bits 1-11: Reserved */
@@ -301,6 +301,7 @@
                                                 /* Bits 14-31: Reserved */
 /* System Clock Gating Control Register 3 */
 
+#if defined(KINETIS_NRNG) && KINETIS_NRNG > 0
 #ifdef KINETIS_K60
 #  define SIM_SCGC3_RNGB              (1 << 0)  /* Bit 0:  RNGB Clock Gate Control (K60) */
 #endif
diff --git a/configs/kwikstik-k40/README.txt b/configs/kwikstik-k40/README.txt
index e50c12df4a03ea9baa90b31161162e6b65c548b9..e274b322f2f8630e8dff071de7b8e244146c8317 100644
--- a/configs/kwikstik-k40/README.txt
+++ b/configs/kwikstik-k40/README.txt
@@ -349,7 +349,7 @@ KwikStik-K40-specific Configuration Options
   	CONFIG_KINETIS_UART3    -- Support UART3
   	CONFIG_KINETIS_UART4    -- Support UART4
   	CONFIG_KINETIS_UART5    -- Support UART5
-  	CONFIG_KINETIS_ETHERNET -- Support Ethernet (K60 only)
+  	CONFIG_KINETIS_ENET     -- Support Ethernet (K60 only)
   	CONFIG_KINETIS_RNGB     -- Support the random number generator(K60 only)
     CONFIG_KINETIS_FLEXCAN0 -- Support FlexCAN0
     CONFIG_KINETIS_FLEXCAN1 -- Support FlexCAN1
diff --git a/configs/kwikstik-k40/ostest/defconfig b/configs/kwikstik-k40/ostest/defconfig
index 2015535fcc78900f10555a745e1f9baf57c29334..9cf3af7f68b423fbb584b789a9ffb18227a02213 100755
--- a/configs/kwikstik-k40/ostest/defconfig
+++ b/configs/kwikstik-k40/ostest/defconfig
@@ -118,7 +118,7 @@ CONFIG_KINETIS_DFU=y
 # CONFIG_KINETIS_UART3 - Support UART3
 # CONFIG_KINETIS_UART4 - Support UART4
 # CONFIG_KINETIS_UART5 - Support UART5
-# CONFIG_KINETIS_ETHERNET - Support Ethernet (K60 only)
+# CONFIG_KINETIS_ENET - Support Ethernet (K60 only)
 # CONFIG_KINETIS_RNGB - Support the random number generator(K60 only)
 # CONFIG_KINETIS_FLEXCAN0 - Support FlexCAN0
 # CONFIG_KINETIS_FLEXCAN1 - Support FlexCAN1
@@ -162,7 +162,7 @@ CONFIG_KINETIS_UART2=n
 CONFIG_KINETIS_UART3=n
 CONFIG_KINETIS_UART4=n
 CONFIG_KINETIS_UART5=y
-CONFIG_KINETIS_ETHERNET=n
+CONFIG_KINETIS_ENET=n
 CONFIG_KINETIS_RNGB=n
 CONFIG_KINETIS_FLEXCAN0=n
 CONFIG_KINETIS_FLEXCAN1=n
diff --git a/configs/twr-k60n512/README.txt b/configs/twr-k60n512/README.txt
index dcbab31ca961d64a80ff3492662d7ea69c6a6b4d..1b7994f10310fdf6b7849d92b83883d392b273b8 100644
--- a/configs/twr-k60n512/README.txt
+++ b/configs/twr-k60n512/README.txt
@@ -483,7 +483,7 @@ TWR-K60N512-specific Configuration Options
   	CONFIG_KINETIS_UART3    -- Support UART3
   	CONFIG_KINETIS_UART4    -- Support UART4
   	CONFIG_KINETIS_UART5    -- Support UART5
-  	CONFIG_KINETIS_ETHERNET -- Support Ethernet (K60 only)
+  	CONFIG_KINETIS_ENET     -- Support Ethernet (K60 only)
   	CONFIG_KINETIS_RNGB     -- Support the random number generator(K60 only)
     CONFIG_KINETIS_FLEXCAN0 -- Support FlexCAN0
     CONFIG_KINETIS_FLEXCAN1 -- Support FlexCAN1
@@ -528,6 +528,11 @@ TWR-K60N512-specific Configuration Options
     CONFIG_KINETIS_UART4PRIO
     CONFIG_KINETIS_UART5PRIO
 
+    CONFIG_KINETIS_EMACTMR_PRIO
+    CONFIG_KINETIS_EMACTX_PRIO
+    CONFIG_KINETIS_EMACRX_PRIO
+    CONFIG_KINETIS_EMACMISC_PRIO
+
   PIN Interrupt Support
 
     CONFIG_GPIO_IRQ          -- Enable pin interrtup support.  Also needs
@@ -550,23 +555,12 @@ TWR-K60N512-specific Configuration Options
 	CONFIG_UARTn_BITS - The number of bits.  Must be either 8 or 8.
 	CONFIG_UARTn_PARTIY - 0=no parity, 1=odd parity, 2=even parity
 
-  TWR-K60N512 LCD Hardware Configuration
-
-    CONFIG_LCD_LANDSCAPE - Define for 320x240 display "landscape"
-      support. Default is this 320x240 "landscape" orientation
-      (this setting is informative only... not used).
-    CONFIG_LCD_PORTRAIT - Define for 240x320 display "portrait"
-      orientation support.  In this orientation, the TWR-K60N512's
-      LCD ribbon cable is at the bottom of the display. Default is
-      320x240 "landscape" orientation.
-    CONFIG_LCD_RPORTRAIT - Define for 240x320 display "reverse
-      portrait" orientation support.  In this orientation, the
-      TWR-K60N512's LCD ribbon cable is at the top of the display.
-      Default is 320x240 "landscape" orientation.
-    CONFIG_LCD_BACKLIGHT - Define to support an adjustable backlight
-      using timer 1.  The granularity of the settings is determined
-      by CONFIG_LCD_MAXPOWER.  Requires CONFIG_KINETIS_TIM1.
+  Kenetis ethernet controller settings
 
+    CONFIG_ENET_NBUFFERS - Number of TX/RX buffers.  The size of one
+        buffer is determined by CONFIG_NET_BUFSIZE.  Default: 8
+    CONFIG_ENET_USEMII - Usee MII mode.  Default: RMII mode.
+ 
 Configurations
 ==============
 
diff --git a/configs/twr-k60n512/ostest/defconfig b/configs/twr-k60n512/ostest/defconfig
index 4d8ee599cfe011e4310402cd701ace0ee9a881e5..94ef1e82f3ae2931ed5288f61596d9ce6d7d48e4 100755
--- a/configs/twr-k60n512/ostest/defconfig
+++ b/configs/twr-k60n512/ostest/defconfig
@@ -111,7 +111,7 @@ CONFIG_KINETIS_DFU=y
 # CONFIG_KINETIS_UART3 - Support UART3
 # CONFIG_KINETIS_UART4 - Support UART4
 # CONFIG_KINETIS_UART5 - Support UART5
-# CONFIG_KINETIS_ETHERNET - Support Ethernet (K60 only)
+# CONFIG_KINETIS_ENET - Support Ethernet (K60 only)
 # CONFIG_KINETIS_RNGB - Support the random number generator(K60 only)
 # CONFIG_KINETIS_FLEXCAN0 - Support FlexCAN0
 # CONFIG_KINETIS_FLEXCAN1 - Support FlexCAN1
@@ -155,7 +155,7 @@ CONFIG_KINETIS_UART2=n
 CONFIG_KINETIS_UART3=n
 CONFIG_KINETIS_UART4=n
 CONFIG_KINETIS_UART5=y
-CONFIG_KINETIS_ETHERNET=n
+CONFIG_KINETIS_ENET=n
 CONFIG_KINETIS_RNGB=n
 CONFIG_KINETIS_FLEXCAN0=n
 CONFIG_KINETIS_FLEXCAN1=n
diff --git a/drivers/net/skeleton.c b/drivers/net/skeleton.c
index 5956f72c6229bc57e75e45c581b5231427cacaff..93dd8a82abe7e14fb4d2ef82e904356525a3f229 100644
--- a/drivers/net/skeleton.c
+++ b/drivers/net/skeleton.c
@@ -67,7 +67,7 @@
 # define CONFIG_skeleton_NINTERFACES 1
 #endif
 
-/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */
+/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per second */
 
 #define skeleton_WDDELAY   (1*CLK_TCK)
 #define skeleton_POLLHSEC  (1*2)
@@ -355,7 +355,7 @@ static int skel_interrupt(int irq, FAR void *context)
 
   skel_receive(skel);
 
-  /* Check is a packet transmission just completed.  If so, call skel_txdone.
+  /* Check if a packet transmission just completed.  If so, call skel_txdone.
    * This may disable further Tx interrupts if there are no pending
    * tansmissions.
    */
@@ -504,7 +504,7 @@ static int skel_ifdown(struct uip_driver_s *dev)
   wd_cancel(skel->sk_txpoll);
   wd_cancel(skel->sk_txtimeout);
 
-  /* Put the the EMAC is its reset, non-operational state.  This should be
+  /* Put the EMAC in its reset, non-operational state.  This should be
    * a known configuration that will guarantee the skel_ifup() always
    * successfully brings the interface back up.
    */
@@ -649,13 +649,13 @@ int skel_initialize(int intf)
   DEBUGASSERT(inf < CONFIG_skeleton_NINTERFACES);
   priv = &g_skel[intf];
 
-   /* Check if a Ethernet chip is recognized at its I/O base */
+  /* Check if a Ethernet chip is recognized at its I/O base */
 
   /* Attach the IRQ to the driver */
 
   if (irq_attach(CONFIG_skeleton_IRQ, skel_interrupt))
     {
-      /* We could not attach the ISR to the the interrupt */
+      /* We could not attach the ISR to the interrupt */
 
       return -EAGAIN;
     }