OSDN Git Service

lpc4088に関わるコードをmbed晩からバックポート
authornyatla <nyatla@47198e57-cb75-475f-84c4-a814cd6f29e0>
Tue, 10 Jun 2014 03:20:36 +0000 (03:20 +0000)
committernyatla <nyatla@47198e57-cb75-475f-84c4-a814cd6f29e0>
Tue, 10 Jun 2014 03:20:36 +0000 (03:20 +0000)
バージョンを++

git-svn-id: http://svn.osdn.jp/svnroot/mimic/trunk@358 47198e57-cb75-475f-84c4-a814cd6f29e0

lib/src/NyLPC_cMiMicEnv.c
lib/src/driver/ethernet/lpc4088/EthDev.c [new file with mode: 0644]
lib/src/driver/ethernet/lpc4088/EthDev_LPC4088.c [new file with mode: 0644]
lib/src/driver/ethernet/lpc4088/EtherDev_LPC4088_protected.h [new file with mode: 0644]
lib/src/driver/ethernet/lpc4088/copy_of_ethernet_api.h [new file with mode: 0644]

index e3203ac..ddc9a4b 100644 (file)
@@ -1,7 +1,7 @@
 #include "NyLPC_cMiMicEnv.h"\r
 #include "../uip/NyLPC_cUipService_protected.h"\r
 \r
-const static char* VERSION="MiMic/1.5.0";\r
+const static char* VERSION="MiMic/1.5.2";\r
 \r
 #if NyLPC_MCU==NyLPC_MCU_LPC4088\r
 const static char* MCU="LPC4088";\r
diff --git a/lib/src/driver/ethernet/lpc4088/EthDev.c b/lib/src/driver/ethernet/lpc4088/EthDev.c
new file mode 100644 (file)
index 0000000..de4e92c
--- /dev/null
@@ -0,0 +1,21 @@
+#include "NyLPC_config.h"\r
+#if NyLPC_MCU==NyLPC_MCU_LPC4088\r
+\r
+#include "../EthDev.h"\r
+#include "EtherDev_LPC4088_protected.h"\r
+\r
+\r
+\r
+const struct TiEthernetDevice* getEthernetDevicePnP(void)\r
+{\r
+       const struct TiEthernetDevice* ret;\r
+       if(EthDev_LPC4088_getInterface(&ret)){\r
+               return ret;\r
+       }\r
+       return NULL;\r
+}\r
+\r
+\r
+#endif\r
+\r
+\r
diff --git a/lib/src/driver/ethernet/lpc4088/EthDev_LPC4088.c b/lib/src/driver/ethernet/lpc4088/EthDev_LPC4088.c
new file mode 100644 (file)
index 0000000..6a5f5c2
--- /dev/null
@@ -0,0 +1,606 @@
+#include "NyLPC_config.h"\r
+#if NyLPC_MCU==NyLPC_MCU_LPC4088\r
+#include "NyLPC_os.h"\r
+#include "copy_of_ethernet_api.h"\r
+#include "NyLPC_IEthernetDevice.h"\r
+#include "NyLPC_cEthernetMM.h"\r
+\r
+\r
+\r
+#define emacSHORT_DELAY_MS                 10\r
+#ifndef configEMAC_INTERRUPT_PRIORITY\r
+    #define configEMAC_INTERRUPT_PRIORITY       5\r
+#endif\r
+////////////////////////////////////////////////////////////////////////////////\r
+// Ethernet Memory\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+#define AHB_SRAM_BANK1_BASE  0x20004000UL\r
+#define RX_DESC_BASE        (AHB_SRAM_BANK1_BASE         )\r
+#define RX_STAT_BASE        (RX_DESC_BASE + NUM_RX_FRAG*(2*4))     /* 2 * uint32_t, see RX_DESC_TypeDef */\r
+#define TX_DESC_BASE        (RX_STAT_BASE + NUM_RX_FRAG*(2*4))     /* 2 * uint32_t, see RX_STAT_TypeDef */\r
+#define TX_STAT_BASE        (TX_DESC_BASE + NUM_TX_FRAG*(2*4))     /* 2 * uint32_t, see TX_DESC_TypeDef */\r
+#define ETH_BUF_BASE           (TX_STAT_BASE + NUM_TX_FRAG*(1*4))     /* 1 * uint32_t, see TX_STAT_TypeDef */\r
+\r
+/**\r
+ * 消費メモリ量は、\r
+ * descriptor = NUM_RX_FRAG*16+NUM_TX_FRAG*12.\r
+ * EthnetBuf=ETH_FRAG_SIZE*NUM_RX_FRAG\r
+ */\r
+\r
+/* RX and TX descriptor and status definitions. */\r
+#define RX_DESC_PACKET(i)   (*(unsigned int *)(RX_DESC_BASE   + 8*i))\r
+#define RX_DESC_CTRL(i)     (*(unsigned int *)(RX_DESC_BASE+4 + 8*i))\r
+#define RX_STAT_INFO(i)     (*(unsigned int *)(RX_STAT_BASE   + 8*i))\r
+#define RX_STAT_HASHCRC(i)  (*(unsigned int *)(RX_STAT_BASE+4 + 8*i))\r
+#define TX_DESC_PACKET(i)   (*(unsigned int *)(TX_DESC_BASE   + 8*i))\r
+#define TX_DESC_CTRL(i)     (*(unsigned int *)(TX_DESC_BASE+4 + 8*i))\r
+#define TX_STAT_INFO(i)     (*(unsigned int *)(TX_STAT_BASE   + 4*i))\r
+#define ETH_BUF(i)          ( ETH_BUF_BASE + ETH_FRAG_SIZE*i )\r
+#define ETH_TX_BUF_BASE ((void*)(ETH_BUF_BASE+ETH_FRAG_SIZE*NUM_RX_FRAG))\r
+\r
+\r
+#define emacWAIT_FOR_LINK_TO_ESTABLISH_MS 500\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+// Ethernet interdface functions\r
+////////////////////////////////////////////////////////////////////////////////\r
+static NyLPC_TBool start(const struct NyLPC_TEthAddr* i_eth_addr,NyLPC_TiEthernetDevice_onEvent i_handler,void* i_param);\r
+static void stop(void);\r
+static void* getRxEthFrame(unsigned short* o_len_of_data);\r
+static void nextRxEthFrame(void);\r
+static struct NyLPC_TTxBufferHeader* allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size);\r
+static void releaseTxBuf(struct NyLPC_TTxBufferHeader* i_buf);\r
+static void sendTxEthFrame(struct NyLPC_TTxBufferHeader* i_buf,unsigned short i_size);\r
+static void processTx(void);\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+// Private\r
+////////////////////////////////////////////////////////////////////////////////\r
+static void emacIsrHandler(unsigned long i_status);\r
+static unsigned int clockselect(void);\r
+static int ethernet_link(void);\r
+static int phy_write(unsigned int PhyReg, unsigned short Data);\r
+static int phy_read(unsigned int PhyReg);\r
+static void prevTxDescriptor(void);\r
+static void prevRxDescriptor(void);\r
+static NyLPC_TUInt32 waitForTxEthFrameEmpty(void);\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+\r
+const static struct TiEthernetDevice _interface_LAN8720=\r
+{\r
+       "LAN8720",\r
+       start,\r
+       stop,\r
+       getRxEthFrame,\r
+       nextRxEthFrame,\r
+       allocTxBuf,\r
+       releaseTxBuf,\r
+       sendTxEthFrame,\r
+       processTx\r
+};\r
+const static struct TiEthernetDevice _interface_DP83848C=\r
+{\r
+       "DP83848C",\r
+       start,\r
+       stop,\r
+       getRxEthFrame,\r
+       nextRxEthFrame,\r
+       allocTxBuf,\r
+       releaseTxBuf,\r
+       sendTxEthFrame,\r
+       processTx\r
+};\r
+\r
+static void* _event_param;\r
+static NyLPC_TiEthernetDevice_onEvent _event_handler;\r
+static unsigned int phy_id;\r
+\r
+/*\r
+ * EthernetDeviceのファクトリー関数。インターフェイスを生成できればtrue\r
+ *\r
+ */\r
+NyLPC_TBool EthDev_LPC4088_getInterface(\r
+       const struct TiEthernetDevice** o_dev)\r
+{\r
+       int regv, tout;\r
+       unsigned int clock = clockselect();\r
+\r
+       LPC_SC->PCONP |= 0x40000000; /* Power Up the EMAC controller. */\r
+       LPC_IOCON->P1_0 &= ~0x07; /* ENET I/O config */\r
+       LPC_IOCON->P1_0 |= 0x01; /* ENET_TXD0 */\r
+       LPC_IOCON->P1_1 &= ~0x07;\r
+       LPC_IOCON->P1_1 |= 0x01; /* ENET_TXD1 */\r
+       LPC_IOCON->P1_4 &= ~0x07;\r
+       LPC_IOCON->P1_4 |= 0x01; /* ENET_TXEN */\r
+       LPC_IOCON->P1_8 &= ~0x07;\r
+       LPC_IOCON->P1_8 |= 0x01; /* ENET_CRS */\r
+       LPC_IOCON->P1_9 &= ~0x07;\r
+       LPC_IOCON->P1_9 |= 0x01; /* ENET_RXD0 */\r
+       LPC_IOCON->P1_10 &= ~0x07;\r
+       LPC_IOCON->P1_10 |= 0x01; /* ENET_RXD1 */\r
+       LPC_IOCON->P1_14 &= ~0x07;\r
+       LPC_IOCON->P1_14 |= 0x01; /* ENET_RX_ER */\r
+       LPC_IOCON->P1_15 &= ~0x07;\r
+       LPC_IOCON->P1_15 |= 0x01; /* ENET_REF_CLK */\r
+       LPC_IOCON->P1_16 &= ~0x07; /* ENET/PHY I/O config */\r
+       LPC_IOCON->P1_16 |= 0x01; /* ENET_MDC */\r
+       LPC_IOCON->P1_17 &= ~0x07;\r
+       LPC_IOCON->P1_17 |= 0x01; /* ENET_MDIO */\r
+\r
+       /* Reset all EMAC internal modules. */\r
+       LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES;\r
+       LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM;\r
+for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */\r
+\r
+       /* Initialize MAC control registers. */\r
+       LPC_EMAC->MAC1 = MAC1_PASS_ALL;\r
+       LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;\r
+       LPC_EMAC->MAXF = ETH_MAX_FLEN;\r
+       LPC_EMAC->CLRT = CLRT_DEF;\r
+       LPC_EMAC->IPGR = IPGR_DEF;\r
+\r
+       /* Enable Reduced MII interface. */\r
+       LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; /* Set clock */\r
+       LPC_EMAC->MCFG |= MCFG_RES_MII; /* and reset */\r
+       LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM |CR_PASS_RX_FILT; /* Enable Reduced MII interface. */\r
+\r
+for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */\r
+\r
+       LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL;\r
+       LPC_EMAC->MCMD = 0;\r
+       LPC_EMAC->SUPP = SUPP_RES_RMII; /* Reset Reduced MII Logic. */\r
+for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */\r
+       LPC_EMAC->SUPP = SUPP_SPEED;\r
+\r
+       phy_write(PHY_REG_BMCR, PHY_BMCR_RESET); /* perform PHY reset */\r
+       for(tout = 0x20000; ; tout--) { /* Wait for hardware reset to end. */\r
+               regv = phy_read(PHY_REG_BMCR);\r
+               if(regv < 0 || tout == 0) {\r
+               return NyLPC_TBool_FALSE; /* Error */\r
+       }\r
+               if(!(regv & PHY_BMCR_RESET)) {\r
+               break; /* Reset complete. */\r
+       }\r
+       }\r
+\r
+       phy_id = (phy_read(PHY_REG_IDR1) << 16);\r
+       phy_id |= (phy_read(PHY_REG_IDR2) & 0XFFF0);\r
+\r
+       switch(phy_id){\r
+       case DP83848C_ID:\r
+               *o_dev=&_interface_DP83848C;\r
+               break;\r
+       case LAN8720_ID:\r
+               *o_dev=&_interface_LAN8720;\r
+               break;\r
+       default:\r
+               return NyLPC_TBool_FALSE; /* Error */\r
+       }\r
+       LPC_EMAC->TxProduceIndex = 0;\r
+       LPC_EMAC->RxConsumeIndex = 0;\r
+       return NyLPC_TBool_TRUE;\r
+}\r
+\r
+\r
+\r
+static NyLPC_TBool start(const struct NyLPC_TEthAddr* i_eth_addr,NyLPC_TiEthernetDevice_onEvent i_handler,void* i_param)\r
+{\r
+       int i;\r
+       //ISRw割り込み設定\r
+       NyLPC_cIsr_setEnetISR(emacIsrHandler);\r
+       _event_handler=i_handler;\r
+       _event_param=i_param;\r
+       /* Set the Ethernet MAC Address registers */\r
+       LPC_EMAC->SA0 = (((uint32_t)(i_eth_addr->addr[0])) << 8 ) | i_eth_addr->addr[1];\r
+       LPC_EMAC->SA1 = (((uint32_t)(i_eth_addr->addr[2])) << 8 ) | i_eth_addr->addr[3];\r
+       LPC_EMAC->SA2 = (((uint32_t)(i_eth_addr->addr[4])) << 8 ) | i_eth_addr->addr[5];\r
+\r
+       //TXメモリマネージャの準備\r
+       NyLPC_cEthernetMM_initialize(ETH_TX_BUF_BASE);\r
+       /* Initialize Tx and Rx DMA Descriptors */\r
+       prevRxDescriptor();\r
+       prevTxDescriptor();\r
+       //wait for link up\r
+       for(i=0;i<5;i++){\r
+               if(ethernet_link()!=0){\r
+                       break;\r
+               }\r
+               NyLPC_cThread_sleep(emacWAIT_FOR_LINK_TO_ESTABLISH_MS);\r
+       }\r
+\r
+       //setup Link\r
+       ethernet_set_link(-1, 0);\r
+\r
+       LPC_EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_MCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN;\r
+       /* Receive Broadcast, Perfect Match Packets */\r
+\r
+       //Ethernetの割込み開始設定\r
+       NyLPC_cIsr_enterCritical();\r
+       {\r
+               LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE; /* Enable EMAC interrupts. */\r
+               LPC_EMAC->IntClear = 0xFFFF; /* Reset all interrupts */\r
+\r
+               LPC_EMAC->Command |= (CR_RX_EN | CR_TX_EN); /* Enable receive and transmit mode of MAC Ethernet core */\r
+               LPC_EMAC->MAC1 |= MAC1_REC_EN;\r
+\r
+        NVIC_SetPriority( ENET_IRQn, configEMAC_INTERRUPT_PRIORITY );\r
+        NVIC_EnableIRQ( ENET_IRQn );\r
+       }\r
+       NyLPC_cIsr_exitCritical();\r
+\r
+       return NyLPC_TBool_TRUE;\r
+}\r
+\r
+\r
+static void stop(void)\r
+{\r
+       NyLPC_cIsr_enterCritical();\r
+       {\r
+           LPC_EMAC->IntEnable &= ~(INT_RX_DONE | INT_TX_DONE);\r
+           LPC_EMAC->IntClear = 0xFFFF;\r
+\r
+        NVIC_DisableIRQ( ENET_IRQn );\r
+       }\r
+       NyLPC_cIsr_exitCritical();\r
+       LPC_EMAC->Command &= ~( CR_RX_EN | CR_TX_EN );\r
+       LPC_EMAC->MAC1 &= ~MAC1_REC_EN;\r
+       //ISR割り込み解除\r
+       NyLPC_cIsr_setEnetISR(NULL);\r
+       //TXメモリマネージャの終了\r
+       NyLPC_cEthernetMM_finalize();\r
+}\r
+\r
+static struct NyLPC_TTxBufferHeader* allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size)\r
+{\r
+       return NyLPC_cEthernetMM_alloc(i_hint,o_size);\r
+}\r
+static void releaseTxBuf(struct NyLPC_TTxBufferHeader* i_buf)\r
+{\r
+       NyLPC_cEthernetMM_release(i_buf);\r
+}\r
+\r
+\r
+/**\r
+*/\r
+static void processTx(void)\r
+{\r
+       waitForTxEthFrameEmpty();\r
+}\r
+\r
+\r
+\r
+/**\r
+ * Ethernetパケットを送信します。\r
+ * allocTxBufで得たバッファか、NyLPC_TTxBufferHeaderのペイロード部分を指定すること。\r
+ * <p>関数仕様</p>\r
+ * この関数は、i_bufが\r
+ * </div>\r
+ */\r
+static void sendTxEthFrame(struct NyLPC_TTxBufferHeader* i_buf,unsigned short i_size)\r
+{\r
+       NyLPC_TUInt32   IndexNext,Index;\r
+\r
+       //サイズ0なら送信の必要なし\r
+       if(i_size == 0)\r
+       {\r
+               return;\r
+       }\r
+       //送信デスクリプタの反映\r
+       IndexNext =waitForTxEthFrameEmpty();\r
+\r
+       //送信対象のメモリブロックを送信中に設定。\r
+//     b=(i_buf+1);\r
+       //送信中のメモリブロックなら無視\r
+       if(i_buf->is_lock){\r
+               return;\r
+       }\r
+       //送信中にセット\r
+       i_buf->is_lock=NyLPC_TUInt8_TRUE;\r
+\r
+       //送信データのセット\r
+       Index = LPC_EMAC->TxProduceIndex;\r
+       if (i_size > ETH_FRAG_SIZE){\r
+               i_size = ETH_FRAG_SIZE;\r
+       }\r
+       //送信処理\r
+       TX_DESC_PACKET( Index ) = ( unsigned long )(i_buf+1);\r
+       //See UM10360.pdf Table 181. Transmit descriptor control word\r
+       TX_DESC_CTRL( Index ) = ((i_size-1) | TCTRL_LAST | TCTRL_INT );\r
+       LPC_EMAC->TxProduceIndex = IndexNext;\r
+       return;\r
+}\r
+/**\r
+ * 送信デスクリプタを準備します。\r
+ */\r
+static void prevTxDescriptor(void)\r
+{\r
+       long x;\r
+       //デスクリプタの設定\r
+       for( x = 0; x < NUM_TX_FRAG; x++ )\r
+       {\r
+               TX_DESC_PACKET( x ) = ( unsigned long ) NULL;\r
+               TX_DESC_CTRL( x ) = 0;\r
+               TX_STAT_INFO( x ) = 0;\r
+       }\r
+       /* Set LPC_EMAC Transmit Descriptor Registers. */\r
+       LPC_EMAC->TxDescriptor =TX_DESC_BASE;\r
+       LPC_EMAC->TxStatus = TX_STAT_BASE;\r
+       LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG - 1;\r
+}\r
+static void prevRxDescriptor(void)\r
+{\r
+       int x;\r
+       //デスクリプタの設定\r
+       for( x = 0; x < NUM_RX_FRAG; x++ )\r
+       {\r
+               /* Allocate the next Ethernet buffer to this descriptor. */\r
+               RX_DESC_PACKET(x) = ETH_BUF(x);\r
+               RX_DESC_CTRL(x) = RCTRL_INT | ( ETH_FRAG_SIZE - 1 );\r
+               RX_STAT_INFO(x) = 0;\r
+               RX_STAT_HASHCRC(x) = 0;\r
+       }\r
+\r
+       /* Set LPC_EMAC Receive Descriptor Registers. */\r
+       LPC_EMAC->RxDescriptor = RX_DESC_BASE;\r
+       LPC_EMAC->RxStatus = RX_STAT_BASE;\r
+       LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG - 1;\r
+\r
+}\r
+\r
+\r
+/**\r
+ * 受信キューの先頭にあるRXフレームのポインタを返します。\r
+ * 関数は、受信キューのポインタを操作しません。続けて読み出したとしても、同じポインターを返します。\r
+ * 制限として、返却したポインタの内容は、一時的に書き換え可としてください。(この制限は将来削除します。)\r
+ * @return\r
+ * 成功した場合、受信データを格納したバッファポインターです。\r
+ * 次回nextRxEthFrameを呼び出すまで有効です。\r
+ */\r
+static void* getRxEthFrame(unsigned short* o_len_of_data)\r
+{\r
+       if( LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex )\r
+       {\r
+               //受信データを返却する。\r
+               *o_len_of_data = (unsigned short)(( RX_STAT_INFO( LPC_EMAC->RxConsumeIndex ) & RINFO_SIZE ) - 3);\r
+               return ( unsigned char * ) RX_DESC_PACKET( LPC_EMAC->RxConsumeIndex );\r
+       }\r
+       return NULL;\r
+}\r
+\r
+\r
+/**\r
+ * 受信キューを進行します。\r
+ */\r
+static void nextRxEthFrame(void)\r
+{\r
+       long lIndex;\r
+       if( LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex )\r
+       {\r
+               //キューすすめる。\r
+               lIndex = LPC_EMAC->RxConsumeIndex;\r
+               lIndex++;\r
+               if( lIndex >= NUM_RX_FRAG )\r
+               {\r
+                       lIndex = 0;\r
+               }\r
+               LPC_EMAC->RxConsumeIndex = lIndex;\r
+       }\r
+}\r
+/********************************************************************************\r
+ * Private functions\r
+ *******************************************************************************/\r
+\r
+\r
+\r
+/**\r
+ * 送信中のイーサフレームを処理する機会を与えて、送信キューが空くまで待ちます。\r
+ * LPC1769の場合は、非同期に更新したディスクリプタの内容から、送信メモリのフラグを更新します。\r
+ * @return\r
+ * 次に書き込むことが出来る送信キュー。\r
+ */\r
+static NyLPC_TUInt32 waitForTxEthFrameEmpty(void)\r
+{\r
+       NyLPC_TUInt32   IndexNext;\r
+       struct NyLPC_TTxBufferHeader *b;\r
+       void* p;\r
+       NyLPC_TUInt32 i;\r
+\r
+       //送信キューの決定\r
+       IndexNext = (LPC_EMAC->TxProduceIndex + 1)%NUM_TX_FRAG;\r
+\r
+       //送信キューフルが解除されるまで待ち\r
+       while(IndexNext == LPC_EMAC->TxConsumeIndex)\r
+       {\r
+               //\r
+               NyLPC_cThread_sleep(emacSHORT_DELAY_MS);\r
+       }\r
+\r
+       //(TxProduceIndex+1)→TxConsumeIndexにあるデータのsentフラグを消去\r
+       for(i=IndexNext;i!=LPC_EMAC->TxConsumeIndex;i=(i+1)%NUM_TX_FRAG)\r
+       {\r
+               p=(void*)TX_DESC_PACKET(i);\r
+               if(p!=NULL){\r
+                       b=((struct NyLPC_TTxBufferHeader*)p)-1;\r
+                       b->is_lock=NyLPC_TUInt8_FALSE;\r
+                       TX_DESC_PACKET(i)=0;\r
+               }\r
+       }\r
+       p=(void*)TX_DESC_PACKET(i);\r
+       if(p!=NULL){\r
+               b=((struct NyLPC_TTxBufferHeader*)p)-1;\r
+               b->is_lock=NyLPC_TUInt8_FALSE;\r
+               TX_DESC_PACKET(i)=0;\r
+       }\r
+       return IndexNext;\r
+}\r
+\r
+//--------------------------------------------------------------------------------\r
+// ISR\r
+//--------------------------------------------------------------------------------\r
+\r
+static void ethernet_set_link(int speed, int duplex) {\r
+    unsigned short phy_data;\r
+    int tout;\r
+\r
+    if((speed < 0) || (speed > 1)) {\r
+        phy_data = PHY_AUTO_NEG;\r
+    } else {\r
+        phy_data = (((unsigned short) speed << 13) |\r
+                    ((unsigned short) duplex << 8));\r
+    }\r
+\r
+    phy_write(PHY_REG_BMCR, phy_data);\r
+\r
+    for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */\r
+\r
+    switch(phy_id) {\r
+        case DP83848C_ID:\r
+            phy_data = phy_read(PHY_REG_STS);\r
+\r
+            if(phy_data & PHY_STS_DUPLEX) {\r
+                LPC_EMAC->MAC2 |= MAC2_FULL_DUP;\r
+                LPC_EMAC->Command |= CR_FULL_DUP;\r
+                LPC_EMAC->IPGT = IPGT_FULL_DUP;\r
+            } else {\r
+            LPC_EMAC->MAC2 &= ~MAC2_FULL_DUP;\r
+                LPC_EMAC->Command &= ~CR_FULL_DUP;\r
+                LPC_EMAC->IPGT = IPGT_HALF_DUP;\r
+            }\r
+\r
+            if(phy_data & PHY_STS_SPEED) {\r
+                LPC_EMAC->SUPP &= ~SUPP_SPEED;\r
+            } else {\r
+                LPC_EMAC->SUPP |= SUPP_SPEED;\r
+            }\r
+            break;\r
+\r
+        case LAN8720_ID:\r
+            phy_data = phy_read(PHY_REG_SCSR);\r
+\r
+            if (phy_data & PHY_SCSR_DUPLEX) {\r
+                LPC_EMAC->MAC2 |= MAC2_FULL_DUP;\r
+                LPC_EMAC->Command |= CR_FULL_DUP;\r
+                LPC_EMAC->IPGT = IPGT_FULL_DUP;\r
+            } else {\r
+                LPC_EMAC->Command &= ~CR_FULL_DUP;\r
+                LPC_EMAC->IPGT = IPGT_HALF_DUP;\r
+            }\r
+\r
+            if(phy_data & PHY_SCSR_100MBIT) {\r
+                LPC_EMAC->SUPP |= SUPP_SPEED;\r
+            } else {\r
+                LPC_EMAC->SUPP &= ~SUPP_SPEED;\r
+            }\r
+\r
+            break;\r
+    }\r
+}\r
+\r
+static int phy_write(unsigned int PhyReg, unsigned short Data) {\r
+    unsigned int timeOut;\r
+\r
+    LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;\r
+    LPC_EMAC->MWTD = Data;\r
+\r
+    for(timeOut = 0; timeOut < MII_WR_TOUT; timeOut++) { /* Wait until operation completed */\r
+        if((LPC_EMAC->MIND & MIND_BUSY) == 0) {\r
+            return 0;\r
+        }\r
+    }\r
+\r
+    return -1;\r
+}\r
+\r
+\r
+static int phy_read(unsigned int PhyReg) {\r
+    unsigned int timeOut;\r
+\r
+    LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg;\r
+    LPC_EMAC->MCMD = MCMD_READ;\r
+\r
+    for(timeOut = 0; timeOut < MII_RD_TOUT; timeOut++) { /* Wait until operation completed */\r
+        if((LPC_EMAC->MIND & MIND_BUSY) == 0) {\r
+            LPC_EMAC->MCMD = 0;\r
+            return LPC_EMAC->MRDD; /* Return a 16-bit value. */\r
+        }\r
+    }\r
+\r
+    return -1;\r
+}\r
+\r
+\r
+//extern unsigned int SystemFrequency;\r
+static unsigned int clockselect(void)\r
+{\r
+  if(SystemCoreClock < 10000000) {\r
+    return 1;\r
+  } else if(SystemCoreClock < 15000000) {\r
+    return 2;\r
+  } else if(SystemCoreClock < 20000000) {\r
+    return 3;\r
+  } else if(SystemCoreClock < 25000000) {\r
+    return 4;\r
+  } else if(SystemCoreClock < 35000000) {\r
+    return 5;\r
+  } else if(SystemCoreClock < 50000000) {\r
+    return 6;\r
+  } else if(SystemCoreClock < 70000000) {\r
+    return 7;\r
+  } else if(SystemCoreClock < 80000000) {\r
+    return 8;\r
+  } else if(SystemCoreClock < 90000000) {\r
+    return 9;\r
+  } else if(SystemCoreClock < 100000000) {\r
+    return 10;\r
+  } else if(SystemCoreClock < 120000000) {\r
+    return 11;\r
+  } else if(SystemCoreClock < 130000000) {\r
+    return 12;\r
+  } else if(SystemCoreClock < 140000000) {\r
+    return 13;\r
+  } else if(SystemCoreClock < 150000000) {\r
+    return 15;\r
+  } else if(SystemCoreClock < 160000000) {\r
+    return 16;\r
+  } else {\r
+    return 0;\r
+  }\r
+}\r
+\r
+static int ethernet_link(void)\r
+{\r
+\r
+    if (phy_id == DP83848C_ID) {\r
+      return (phy_read(PHY_REG_STS) & PHY_STS_LINK);\r
+    }\r
+    else { // LAN8720_ID\r
+      return (phy_read(PHY_REG_BMSR) & PHY_BMSR_LINK);\r
+    }\r
+}\r
+//--------------------------------------------------------------------------------\r
+// ISR\r
+//--------------------------------------------------------------------------------\r
+\r
+\r
+/**\r
+ * EMACからのハンドラ\r
+ */\r
+static void emacIsrHandler(unsigned long i_status)\r
+{\r
+       if( i_status & INT_RX_DONE )\r
+       {\r
+               _event_handler(_event_param,NyLPC_TiEthernetDevice_EVENT_ON_RX);\r
+       }\r
+       if( i_status & INT_TX_DONE )\r
+       {\r
+               _event_handler(_event_param,NyLPC_TiEthernetDevice_EVENT_ON_TX);\r
+       }\r
+}\r
+\r
+#endif\r
+\r
+\r
+\r
diff --git a/lib/src/driver/ethernet/lpc4088/EtherDev_LPC4088_protected.h b/lib/src/driver/ethernet/lpc4088/EtherDev_LPC4088_protected.h
new file mode 100644 (file)
index 0000000..30209ff
--- /dev/null
@@ -0,0 +1,23 @@
+/*\r
+ * This is part of EthDev_LPC17xx.h\r
+ */\r
+\r
+#ifndef EtherDev_LPC4088_protected_h\r
+#define EtherDev_LPC4088_protected_h\r
+#include "NyLPC_stdlib.h"\r
+#include "../NyLPC_IEthernetDevice.h"\r
+#include "EthDev_LPC17xx.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+\r
+NyLPC_TBool EthDev_LPC4088_getInterface(\r
+       const struct TiEthernetDevice** o_dev);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+\r
+#endif\r
+\r
diff --git a/lib/src/driver/ethernet/lpc4088/copy_of_ethernet_api.h b/lib/src/driver/ethernet/lpc4088/copy_of_ethernet_api.h
new file mode 100644 (file)
index 0000000..1713252
--- /dev/null
@@ -0,0 +1,310 @@
+//Copy from mbed HAL\r
+//https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/ethernet_api.c\r
+\r
+#include <string.h>\r
+\r
+#include "ethernet_api.h"\r
+#include "cmsis.h"\r
+#include "mbed_interface.h"\r
+#include "toolchain.h"\r
+#include "error.h"\r
+\r
+#define NUM_RX_FRAG         3           /* Num.of RX Fragments. */\r
+#define NUM_TX_FRAG         16           /* Num.of TX Fragments. */\r
+#define ETH_FRAG_SIZE       1536        /* Packet Fragment size 1536 Bytes   */\r
+\r
+#define ETH_MAX_FLEN        1536        /* Max. Ethernet Frame Size          */\r
+\r
+#define ETHERNET_ADDR_SIZE 6\r
+\r
+PACKED struct RX_DESC_TypeDef { /* RX Descriptor struct */\r
+   unsigned int Packet;\r
+   unsigned int Ctrl;\r
+};\r
+typedef struct RX_DESC_TypeDef RX_DESC_TypeDef;\r
+\r
+PACKED struct RX_STAT_TypeDef { /* RX Status struct */\r
+   unsigned int Info;\r
+   unsigned int HashCRC;\r
+};\r
+typedef struct RX_STAT_TypeDef RX_STAT_TypeDef;\r
+\r
+PACKED struct TX_DESC_TypeDef { /* TX Descriptor struct */\r
+   unsigned int Packet;\r
+   unsigned int Ctrl;\r
+};\r
+typedef struct TX_DESC_TypeDef TX_DESC_TypeDef;\r
+\r
+PACKED struct TX_STAT_TypeDef { /* TX Status struct */\r
+   unsigned int Info;\r
+};\r
+typedef struct TX_STAT_TypeDef TX_STAT_TypeDef;\r
+\r
+/* MAC Configuration Register 1 */\r
+#define MAC1_REC_EN 0x00000001 /* Receive Enable */\r
+#define MAC1_PASS_ALL 0x00000002 /* Pass All Receive Frames */\r
+#define MAC1_RX_FLOWC 0x00000004 /* RX Flow Control */\r
+#define MAC1_TX_FLOWC 0x00000008 /* TX Flow Control */\r
+#define MAC1_LOOPB 0x00000010 /* Loop Back Mode */\r
+#define MAC1_RES_TX 0x00000100 /* Reset TX Logic */\r
+#define MAC1_RES_MCS_TX 0x00000200 /* Reset MAC TX Control Sublayer */\r
+#define MAC1_RES_RX 0x00000400 /* Reset RX Logic */\r
+#define MAC1_RES_MCS_RX 0x00000800 /* Reset MAC RX Control Sublayer */\r
+#define MAC1_SIM_RES 0x00004000 /* Simulation Reset */\r
+#define MAC1_SOFT_RES 0x00008000 /* Soft Reset MAC */\r
+\r
+/* MAC Configuration Register 2 */\r
+#define MAC2_FULL_DUP 0x00000001 /* Full Duplex Mode */\r
+#define MAC2_FRM_LEN_CHK 0x00000002 /* Frame Length Checking */\r
+#define MAC2_HUGE_FRM_EN 0x00000004 /* Huge Frame Enable */\r
+#define MAC2_DLY_CRC 0x00000008 /* Delayed CRC Mode */\r
+#define MAC2_CRC_EN 0x00000010 /* Append CRC to every Frame */\r
+#define MAC2_PAD_EN 0x00000020 /* Pad all Short Frames */\r
+#define MAC2_VLAN_PAD_EN 0x00000040 /* VLAN Pad Enable */\r
+#define MAC2_ADET_PAD_EN 0x00000080 /* Auto Detect Pad Enable */\r
+#define MAC2_PPREAM_ENF 0x00000100 /* Pure Preamble Enforcement */\r
+#define MAC2_LPREAM_ENF 0x00000200 /* Long Preamble Enforcement */\r
+#define MAC2_NO_BACKOFF 0x00001000 /* No Backoff Algorithm */\r
+#define MAC2_BACK_PRESSURE 0x00002000 /* Backoff Presurre / No Backoff */\r
+#define MAC2_EXCESS_DEF 0x00004000 /* Excess Defer */\r
+\r
+/* Back-to-Back Inter-Packet-Gap Register */\r
+#define IPGT_FULL_DUP 0x00000015 /* Recommended value for Full Duplex */\r
+#define IPGT_HALF_DUP 0x00000012 /* Recommended value for Half Duplex */\r
+\r
+/* Non Back-to-Back Inter-Packet-Gap Register */\r
+#define IPGR_DEF 0x00000012 /* Recommended value */\r
+\r
+/* Collision Window/Retry Register */\r
+#define CLRT_DEF 0x0000370F /* Default value */\r
+\r
+/* PHY Support Register */\r
+#define SUPP_SPEED 0x00000100 /* Reduced MII Logic Current Speed */\r
+//#define SUPP_RES_RMII 0x00000800 /* Reset Reduced MII Logic */\r
+#define SUPP_RES_RMII 0x00000000 /* Reset Reduced MII Logic */\r
+\r
+/* Test Register */\r
+#define TEST_SHCUT_PQUANTA 0x00000001 /* Shortcut Pause Quanta */\r
+#define TEST_TST_PAUSE 0x00000002 /* Test Pause */\r
+#define TEST_TST_BACKP 0x00000004 /* Test Back Pressure */\r
+\r
+/* MII Management Configuration Register */\r
+#define MCFG_SCAN_INC 0x00000001 /* Scan Increment PHY Address */\r
+#define MCFG_SUPP_PREAM 0x00000002 /* Suppress Preamble */\r
+#define MCFG_CLK_SEL 0x0000003C /* Clock Select Mask */\r
+#define MCFG_RES_MII 0x00008000 /* Reset MII Management Hardware */\r
+\r
+/* MII Management Command Register */\r
+#define MCMD_READ 0x00000001 /* MII Read */\r
+#define MCMD_SCAN 0x00000002 /* MII Scan continuously */\r
+\r
+#define MII_WR_TOUT 0x00050000 /* MII Write timeout count */\r
+#define MII_RD_TOUT 0x00050000 /* MII Read timeout count */\r
+\r
+/* MII Management Address Register */\r
+#define MADR_REG_ADR 0x0000001F /* MII Register Address Mask */\r
+#define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */\r
+\r
+/* MII Management Indicators Register */\r
+#define MIND_BUSY 0x00000001 /* MII is Busy */\r
+#define MIND_SCAN 0x00000002 /* MII Scanning in Progress */\r
+#define MIND_NOT_VAL 0x00000004 /* MII Read Data not valid */\r
+#define MIND_MII_LINK_FAIL 0x00000008 /* MII Link Failed */\r
+\r
+/* Command Register */\r
+#define CR_RX_EN 0x00000001 /* Enable Receive */\r
+#define CR_TX_EN 0x00000002 /* Enable Transmit */\r
+#define CR_REG_RES 0x00000008 /* Reset Host Registers */\r
+#define CR_TX_RES 0x00000010 /* Reset Transmit Datapath */\r
+#define CR_RX_RES 0x00000020 /* Reset Receive Datapath */\r
+#define CR_PASS_RUNT_FRM 0x00000040 /* Pass Runt Frames */\r
+#define CR_PASS_RX_FILT 0x00000080 /* Pass RX Filter */\r
+#define CR_TX_FLOW_CTRL 0x00000100 /* TX Flow Control */\r
+#define CR_RMII 0x00000200 /* Reduced MII Interface */\r
+#define CR_FULL_DUP 0x00000400 /* Full Duplex */\r
+\r
+/* Status Register */\r
+#define SR_RX_EN 0x00000001 /* Enable Receive */\r
+#define SR_TX_EN 0x00000002 /* Enable Transmit */\r
+\r
+/* Transmit Status Vector 0 Register */\r
+#define TSV0_CRC_ERR 0x00000001 /* CRC error */\r
+#define TSV0_LEN_CHKERR 0x00000002 /* Length Check Error */\r
+#define TSV0_LEN_OUTRNG 0x00000004 /* Length Out of Range */\r
+#define TSV0_DONE 0x00000008 /* Tramsmission Completed */\r
+#define TSV0_MCAST 0x00000010 /* Multicast Destination */\r
+#define TSV0_BCAST 0x00000020 /* Broadcast Destination */\r
+#define TSV0_PKT_DEFER 0x00000040 /* Packet Deferred */\r
+#define TSV0_EXC_DEFER 0x00000080 /* Excessive Packet Deferral */\r
+#define TSV0_EXC_COLL 0x00000100 /* Excessive Collision */\r
+#define TSV0_LATE_COLL 0x00000200 /* Late Collision Occured */\r
+#define TSV0_GIANT 0x00000400 /* Giant Frame */\r
+#define TSV0_UNDERRUN 0x00000800 /* Buffer Underrun */\r
+#define TSV0_BYTES 0x0FFFF000 /* Total Bytes Transferred */\r
+#define TSV0_CTRL_FRAME 0x10000000 /* Control Frame */\r
+#define TSV0_PAUSE 0x20000000 /* Pause Frame */\r
+#define TSV0_BACK_PRESS 0x40000000 /* Backpressure Method Applied */\r
+#define TSV0_VLAN 0x80000000 /* VLAN Frame */\r
+\r
+/* Transmit Status Vector 1 Register */\r
+#define TSV1_BYTE_CNT 0x0000FFFF /* Transmit Byte Count */\r
+#define TSV1_COLL_CNT 0x000F0000 /* Transmit Collision Count */\r
+\r
+/* Receive Status Vector Register */\r
+#define RSV_BYTE_CNT 0x0000FFFF /* Receive Byte Count */\r
+#define RSV_PKT_IGNORED 0x00010000 /* Packet Previously Ignored */\r
+#define RSV_RXDV_SEEN 0x00020000 /* RXDV Event Previously Seen */\r
+#define RSV_CARR_SEEN 0x00040000 /* Carrier Event Previously Seen */\r
+#define RSV_REC_CODEV 0x00080000 /* Receive Code Violation */\r
+#define RSV_CRC_ERR 0x00100000 /* CRC Error */\r
+#define RSV_LEN_CHKERR 0x00200000 /* Length Check Error */\r
+#define RSV_LEN_OUTRNG 0x00400000 /* Length Out of Range */\r
+#define RSV_REC_OK 0x00800000 /* Frame Received OK */\r
+#define RSV_MCAST 0x01000000 /* Multicast Frame */\r
+#define RSV_BCAST 0x02000000 /* Broadcast Frame */\r
+#define RSV_DRIB_NIBB 0x04000000 /* Dribble Nibble */\r
+#define RSV_CTRL_FRAME 0x08000000 /* Control Frame */\r
+#define RSV_PAUSE 0x10000000 /* Pause Frame */\r
+#define RSV_UNSUPP_OPC 0x20000000 /* Unsupported Opcode */\r
+#define RSV_VLAN 0x40000000 /* VLAN Frame */\r
+\r
+/* Flow Control Counter Register */\r
+#define FCC_MIRR_CNT 0x0000FFFF /* Mirror Counter */\r
+#define FCC_PAUSE_TIM 0xFFFF0000 /* Pause Timer */\r
+\r
+/* Flow Control Status Register */\r
+#define FCS_MIRR_CNT 0x0000FFFF /* Mirror Counter Current */\r
+\r
+/* Receive Filter Control Register */\r
+#define RFC_UCAST_EN 0x00000001 /* Accept Unicast Frames Enable */\r
+#define RFC_BCAST_EN 0x00000002 /* Accept Broadcast Frames Enable */\r
+#define RFC_MCAST_EN 0x00000004 /* Accept Multicast Frames Enable */\r
+#define RFC_UCAST_HASH_EN 0x00000008 /* Accept Unicast Hash Filter Frames */\r
+#define RFC_MCAST_HASH_EN 0x00000010 /* Accept Multicast Hash Filter Fram.*/\r
+#define RFC_PERFECT_EN 0x00000020 /* Accept Perfect Match Enable */\r
+#define RFC_MAGP_WOL_EN 0x00001000 /* Magic Packet Filter WoL Enable */\r
+#define RFC_PFILT_WOL_EN 0x00002000 /* Perfect Filter WoL Enable */\r
+\r
+/* Receive Filter WoL Status/Clear Registers */\r
+#define WOL_UCAST 0x00000001 /* Unicast Frame caused WoL */\r
+#define WOL_BCAST 0x00000002 /* Broadcast Frame caused WoL */\r
+#define WOL_MCAST 0x00000004 /* Multicast Frame caused WoL */\r
+#define WOL_UCAST_HASH 0x00000008 /* Unicast Hash Filter Frame WoL */\r
+#define WOL_MCAST_HASH 0x00000010 /* Multicast Hash Filter Frame WoL */\r
+#define WOL_PERFECT 0x00000020 /* Perfect Filter WoL */\r
+#define WOL_RX_FILTER 0x00000080 /* RX Filter caused WoL */\r
+#define WOL_MAG_PACKET 0x00000100 /* Magic Packet Filter caused WoL */\r
+\r
+/* Interrupt Status/Enable/Clear/Set Registers */\r
+#define INT_RX_OVERRUN 0x00000001 /* Overrun Error in RX Queue */\r
+#define INT_RX_ERR 0x00000002 /* Receive Error */\r
+#define INT_RX_FIN 0x00000004 /* RX Finished Process Descriptors */\r
+#define INT_RX_DONE 0x00000008 /* Receive Done */\r
+#define INT_TX_UNDERRUN 0x00000010 /* Transmit Underrun */\r
+#define INT_TX_ERR 0x00000020 /* Transmit Error */\r
+#define INT_TX_FIN 0x00000040 /* TX Finished Process Descriptors */\r
+#define INT_TX_DONE 0x00000080 /* Transmit Done */\r
+#define INT_SOFT_INT 0x00001000 /* Software Triggered Interrupt */\r
+#define INT_WAKEUP 0x00002000 /* Wakeup Event Interrupt */\r
+\r
+/* Power Down Register */\r
+#define PD_POWER_DOWN 0x80000000 /* Power Down MAC */\r
+\r
+/* RX Descriptor Control Word */\r
+#define RCTRL_SIZE 0x000007FF /* Buffer size mask */\r
+#define RCTRL_INT 0x80000000 /* Generate RxDone Interrupt */\r
+\r
+/* RX Status Hash CRC Word */\r
+#define RHASH_SA 0x000001FF /* Hash CRC for Source Address */\r
+#define RHASH_DA 0x001FF000 /* Hash CRC for Destination Address */\r
+\r
+/* RX Status Information Word */\r
+#define RINFO_SIZE 0x000007FF /* Data size in bytes */\r
+#define RINFO_CTRL_FRAME 0x00040000 /* Control Frame */\r
+#define RINFO_VLAN 0x00080000 /* VLAN Frame */\r
+#define RINFO_FAIL_FILT 0x00100000 /* RX Filter Failed */\r
+#define RINFO_MCAST 0x00200000 /* Multicast Frame */\r
+#define RINFO_BCAST 0x00400000 /* Broadcast Frame */\r
+#define RINFO_CRC_ERR 0x00800000 /* CRC Error in Frame */\r
+#define RINFO_SYM_ERR 0x01000000 /* Symbol Error from PHY */\r
+#define RINFO_LEN_ERR 0x02000000 /* Length Error */\r
+#define RINFO_RANGE_ERR 0x04000000 /* Range Error (exceeded max. size) */\r
+#define RINFO_ALIGN_ERR 0x08000000 /* Alignment Error */\r
+#define RINFO_OVERRUN 0x10000000 /* Receive overrun */\r
+#define RINFO_NO_DESCR 0x20000000 /* No new Descriptor available */\r
+#define RINFO_LAST_FLAG 0x40000000 /* Last Fragment in Frame */\r
+#define RINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */\r
+\r
+//#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_CRC_ERR | RINFO_SYM_ERR | RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN)\r
+#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_SYM_ERR | RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN)\r
+\r
+\r
+/* TX Descriptor Control Word */\r
+#define TCTRL_SIZE 0x000007FF /* Size of data buffer in bytes */\r
+#define TCTRL_OVERRIDE 0x04000000 /* Override Default MAC Registers */\r
+#define TCTRL_HUGE 0x08000000 /* Enable Huge Frame */\r
+#define TCTRL_PAD 0x10000000 /* Pad short Frames to 64 bytes */\r
+#define TCTRL_CRC 0x20000000 /* Append a hardware CRC to Frame */\r
+#define TCTRL_LAST 0x40000000 /* Last Descriptor for TX Frame */\r
+#define TCTRL_INT 0x80000000 /* Generate TxDone Interrupt */\r
+\r
+/* TX Status Information Word */\r
+#define TINFO_COL_CNT 0x01E00000 /* Collision Count */\r
+#define TINFO_DEFER 0x02000000 /* Packet Deferred (not an error) */\r
+#define TINFO_EXCESS_DEF 0x04000000 /* Excessive Deferral */\r
+#define TINFO_EXCESS_COL 0x08000000 /* Excessive Collision */\r
+#define TINFO_LATE_COL 0x10000000 /* Late Collision Occured */\r
+#define TINFO_UNDERRUN 0x20000000 /* Transmit Underrun */\r
+#define TINFO_NO_DESCR 0x40000000 /* No new Descriptor available */\r
+#define TINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */\r
+\r
+/* ENET Device Revision ID */\r
+#define OLD_EMAC_MODULE_ID 0x39022000 /* Rev. ID for first rev '-' */\r
+\r
+/* DP83848C PHY Registers */\r
+#define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */\r
+#define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */\r
+#define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */\r
+#define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */\r
+#define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */\r
+#define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */\r
+#define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */\r
+#define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */\r
+\r
+/* PHY Extended Registers */\r
+#define PHY_REG_STS 0x10 /* Status Register */\r
+#define PHY_REG_MICR 0x11 /* MII Interrupt Control Register */\r
+#define PHY_REG_MISR 0x12 /* MII Interrupt Status Register */\r
+#define PHY_REG_FCSCR 0x14 /* False Carrier Sense Counter */\r
+#define PHY_REG_RECR 0x15 /* Receive Error Counter */\r
+#define PHY_REG_PCSR 0x16 /* PCS Sublayer Config. and Status */\r
+#define PHY_REG_RBR 0x17 /* RMII and Bypass Register */\r
+#define PHY_REG_LEDCR 0x18 /* LED Direct Control Register */\r
+#define PHY_REG_PHYCR 0x19 /* PHY Control Register */\r
+#define PHY_REG_10BTSCR 0x1A /* 10Base-T Status/Control Register */\r
+#define PHY_REG_CDCTRL1 0x1B /* CD Test Control and BIST Extens. */\r
+#define PHY_REG_EDCR 0x1D /* Energy Detect Control Register */\r
+\r
+#define PHY_REG_SCSR 0x1F /* PHY Special Control/Status Register */\r
+\r
+#define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */\r
+#define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */\r
+#define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */\r
+#define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */\r
+#define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */\r
+\r
+#define DP83848C_DEF_ADR 0x0100 /* Default PHY device address */\r
+#define DP83848C_ID 0x20005C90 /* PHY Identifier - DP83848C */\r
+\r
+#define LAN8720_ID 0x0007C0F0 /* PHY Identifier - LAN8720 */\r
+\r
+#define PHY_STS_LINK 0x0001 /* PHY Status Link Mask */\r
+#define PHY_STS_SPEED 0x0002 /* PHY Status Speed Mask */\r
+#define PHY_STS_DUPLEX 0x0004 /* PHY Status Duplex Mask */\r
+\r
+#define PHY_BMCR_RESET 0x8000 /* PHY Reset */\r
+\r
+#define PHY_BMSR_LINK 0x0004 /* PHY BMSR Link valid */\r
+\r
+#define PHY_SCSR_100MBIT 0x0008 /* Speed: 1=100 MBit, 0=10Mbit */\r
+#define PHY_SCSR_DUPLEX 0x0010 /* PHY Duplex Mask */\r