diff --git a/include/libopencm3/ethernet/mac.h b/include/libopencm3/ethernet/mac.h
new file mode 100644
index 00000000..26580577
--- /dev/null
+++ b/include/libopencm3/ethernet/mac.h
@@ -0,0 +1,46 @@
+/** @defgroup ethernet_mac_defines MAC Generic Defines
+ *
+ * @brief Defined Constants and Types for the Ethernet MAC
+ *
+ * @ingroup ETH
+ *
+ * @version 1.0.0
+ *
+ * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian
+ *
+ * @date 1 September 2013
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2013 Frantisek Burian
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+/**@{*/
+
+#if defined(STM32F1)
+# include
+#elif defined(STM32F4)
+# include
+#else
+# error "stm32 family not defined."
+#endif
+
+/**@}*/
+
+
diff --git a/include/libopencm3/ethernet/mac_stm32fxx7.h b/include/libopencm3/ethernet/mac_stm32fxx7.h
new file mode 100644
index 00000000..b70a49a4
--- /dev/null
+++ b/include/libopencm3/ethernet/mac_stm32fxx7.h
@@ -0,0 +1,753 @@
+/** @defgroup ethernet_mac_stm32fxx7_defines MAC STM32Fxx7 Defines
+ *
+ * @brief Defined Constants and Types for the Ethernet MAC for STM32Fxx7
+ * chips
+ *
+ * @ingroup ETH
+ *
+ * @version 1.0.0
+ *
+ * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian
+ *
+ * @date 1 September 2013
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2013 Frantisek Burian
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+#ifndef LIBOPENCM3_ETHERNET_H
+#define LIBOPENCM3_ETHERNET_H
+
+#include
+#include
+
+/**@{*/
+
+/* Ethernet MAC registers */
+#define ETH_MACCR MMIO32(ETHERNET_BASE + 0x00)
+#define ETH_MACFFR MMIO32(ETHERNET_BASE + 0x04)
+#define ETH_MACHTHR MMIO32(ETHERNET_BASE + 0x08)
+#define ETH_MACHTLR MMIO32(ETHERNET_BASE + 0x0C)
+#define ETH_MACMIIAR MMIO32(ETHERNET_BASE + 0x10)
+#define ETH_MACMIIDR MMIO32(ETHERNET_BASE + 0x14)
+#define ETH_MACFCR MMIO32(ETHERNET_BASE + 0x18)
+#define ETH_MACVLANTR MMIO32(ETHERNET_BASE + 0x1C)
+#define ETH_MACRWUFFR MMIO32(ETHERNET_BASE + 0x28)
+#define ETH_MACPMTCSR MMIO32(ETHERNET_BASE + 0x2C)
+/* not available on F1 ?*/
+#define ETH_MACDBGR MMIO32(ETHERNET_BASE + 0x34)
+#define ETH_MACSR MMIO32(ETHERNET_BASE + 0x38)
+#define ETH_MACIMR MMIO32(ETHERNET_BASE + 0x3C)
+
+/* i=[0..3] */
+#define ETH_MACAHR(i) MMIO32(ETHERNET_BASE + 0x40+i*8)
+/* i=[0..3] */
+#define ETH_MACALR(i) MMIO32(ETHERNET_BASE + 0x44+i*8)
+
+/* Ethernet MMC registers */
+#define ETH_MMCCR MMIO32(ETHERNET_BASE + 0x100)
+#define ETH_MMCRIR MMIO32(ETHERNET_BASE + 0x104)
+#define ETH_MMCTIR MMIO32(ETHERNET_BASE + 0x108)
+#define ETH_MMCRIMR MMIO32(ETHERNET_BASE + 0x10C)
+#define ETH_MMCTIMR MMIO32(ETHERNET_BASE + 0x110)
+#define ETH_MMCTGFSCCR MMIO32(ETHERNET_BASE + 0x14C)
+#define ETH_MMCTGFMSCCR MMIO32(ETHERNET_BASE + 0x150)
+#define ETH_MMCTGFCR MMIO32(ETHERNET_BASE + 0x168)
+#define ETH_MMCRFCECR MMIO32(ETHERNET_BASE + 0x194)
+#define ETH_MMCRFAECR MMIO32(ETHERNET_BASE + 0x198)
+#define ETH_MMCRGUFCR MMIO32(ETHERNET_BASE + 0x1C4)
+
+/* Ethrenet IEEE 1588 time stamp registers */
+#define ETH_PTPTSCR MMIO32(ETHERNET_BASE + 0x700)
+#define ETH_PTPSSIR MMIO32(ETHERNET_BASE + 0x704)
+#define ETH_PTPTSHR MMIO32(ETHERNET_BASE + 0x708)
+#define ETH_PTPTSLR MMIO32(ETHERNET_BASE + 0x70C)
+#define ETH_PTPTSHUR MMIO32(ETHERNET_BASE + 0x710)
+#define ETH_PTPTSLUR MMIO32(ETHERNET_BASE + 0x714)
+#define ETH_PTPTSAR MMIO32(ETHERNET_BASE + 0x718)
+#define ETH_PTPTTHR MMIO32(ETHERNET_BASE + 0x71C)
+#define ETH_PTPTTLR MMIO32(ETHERNET_BASE + 0x720)
+/* not available on F1 ?*/
+#define ETH_PTPTSSR MMIO32(ETHERNET_BASE + 0x728)
+
+/* Ethernet DMA registers */
+#define ETH_DMABMR MMIO32(ETHERNET_BASE + 0x1000)
+#define ETH_DMATPDR MMIO32(ETHERNET_BASE + 0x1004)
+#define ETH_DMARPDR MMIO32(ETHERNET_BASE + 0x1008)
+#define ETH_DMARDLAR MMIO32(ETHERNET_BASE + 0x100C)
+#define ETH_DMATDLAR MMIO32(ETHERNET_BASE + 0x1010)
+#define ETH_DMASR MMIO32(ETHERNET_BASE + 0x1014)
+#define ETH_DMAOMR MMIO32(ETHERNET_BASE + 0x1018)
+#define ETH_DMAIER MMIO32(ETHERNET_BASE + 0x101C)
+#define ETH_DMAMFBOCR MMIO32(ETHERNET_BASE + 0x1020)
+#define ETH_DMACHTDR MMIO32(ETHERNET_BASE + 0x1048)
+#define ETH_DMACHRDR MMIO32(ETHERNET_BASE + 0x104C)
+#define ETH_DMACHTBAR MMIO32(ETHERNET_BASE + 0x1050)
+#define ETH_DMACHRBAR MMIO32(ETHERNET_BASE + 0x1054)
+
+/* Ethernet Buffer Descriptors */
+#define ETH_DES(n, base) MMIO32((base) + (n)*4)
+#define ETH_DES0(base) ETH_DES(0, base)
+#define ETH_DES1(base) ETH_DES(1, base)
+#define ETH_DES2(base) ETH_DES(2, base)
+#define ETH_DES3(base) ETH_DES(3, base)
+
+/* Ethernet Extended buffer Descriptors */
+#define ETH_DES4(base) ETH_DES(4, base)
+#define ETH_DES5(base) ETH_DES(5, base)
+#define ETH_DES6(base) ETH_DES(6, base)
+#define ETH_DES7(base) ETH_DES(7, base)
+
+/*---------------------------------------------------------------------------*/
+/* MACCR --------------------------------------------------------------------*/
+
+#define ETH_MACCR_RE (1<<2)
+#define ETH_MACCR_TE (1<<3)
+#define ETH_MACCR_DC (1<<4)
+
+#define ETH_MACCR_BL_SHIFT 5
+#define ETH_MACCR_BL (3 << ETH_MACCR_BL_SHIFT)
+#define ETH_MACCR_BL_MIN10 (0 << ETH_MACCR_BL_SHIFT)
+#define ETH_MACCR_BL_MIN8 (1 << ETH_MACCR_BL_SHIFT)
+#define ETH_MACCR_BL_MIN4 (2 << ETH_MACCR_BL_SHIFT)
+#define ETH_MACCR_BL_MIN1 (3 << ETH_MACCR_BL_SHIFT)
+
+#define ETH_MACCR_APCS (1<<7)
+#define ETH_MACCR_RD (1<<9)
+#define ETH_MACCR_IPCO (1<<10)
+#define ETH_MACCR_DM (1<<11)
+#define ETH_MACCR_LM (1<<12)
+#define ETH_MACCR_ROD (1<<13)
+#define ETH_MACCR_FES (1<<14)
+#define ETH_MACCR_CSD (1<<16)
+
+#define ETH_MACCR_IFG_SHIFT 17
+#define ETH_MACCR_IFG (7<Defined Constants and Types for the Ethernet PHY
+ *
+ * @ingroup ETH
+ *
+ * @version 1.0.0
+ *
+ * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian
+ *
+ * @date 1 September 2013
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2013 Frantisek Burian
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+#ifndef LIBOPENCM3_PHY_H
+#define LIBOPENCM3_PHY_H
+
+#include
+
+/**@{*/
+
+/* Registers */
+
+#define PHY_REG_BCR 0x00
+#define PHY_REG_BSR 0x01
+#define PHY_REG_ID1 0x02
+#define PHY_REG_ID2 0x03
+#define PHY_REG_ANTX 0x04
+#define PHY_REG_ANRX 0x05
+#define PHY_REG_ANEXP 0x06
+#define PHY_REG_ANNPTX 0x07
+#define PHY_REG_ANNPRX 0x08
+
+#define PHY_REG_BCR_COLTEST (1<<7)
+#define PHY_REG_BCR_FD (1<<8)
+#define PHY_REG_BCR_ANRST (1<<9)
+#define PHY_REG_BCR_ISOLATE (1<<10)
+#define PHY_REG_BCR_POWERDN (1<<11)
+#define PHY_REG_BCR_AN (1<<12)
+#define PHY_REG_BCR_100M (1<<13)
+#define PHY_REG_BCR_LOOPBACK (1<<14)
+#define PHY_REG_BCR_RESET (1<<15)
+
+#define PHY_REG_BSR_JABBER (1<<1)
+#define PHY_REG_BSR_UP (1<<2)
+#define PHY_REG_BSR_FAULT (1<<4)
+#define PHY_REG_BSR_ANDONE (1<<5)
+
+
+enum phy_status {
+ LINK_DOWN,
+ LINK_HD_10M,
+ LINK_HD_100M,
+ LINK_HD_1000M,
+ LINK_HD_10000M,
+ LINK_FD_10M,
+ LINK_FD_100M,
+ LINK_FD_1000M,
+ LINK_FD_10000M,
+};
+
+void phy_reset(void);
+bool phy_link_isup(void);
+
+enum phy_status phy_link_status(void);
+
+void phy_autoneg_force(enum phy_status mode);
+void phy_autoneg_enable(void);
+
+/**@}*/
+
+
+#endif /* LIBOPENCM3_PHY_H__ */
diff --git a/include/libopencm3/ethernet/phy_ksz8051mll.h b/include/libopencm3/ethernet/phy_ksz8051mll.h
new file mode 100644
index 00000000..ad37da1c
--- /dev/null
+++ b/include/libopencm3/ethernet/phy_ksz8051mll.h
@@ -0,0 +1,60 @@
+/** @defgroup ethernet_phy_ksz8051mll_defines PHY KSZ8051mll Defines
+ *
+ * @brief Defined Constants and Types for the Ethernet PHY KSZ8051mll
+ * chips
+ *
+ * @ingroup ETH
+ *
+ * @version 1.0.0
+ *
+ * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian
+ *
+ * @date 1 September 2013
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2013 Frantisek Burian
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+#ifndef LIBOPENCM3_PHY_KSZ8051MLL_H
+#define LIBOPENCM3_PHY_KSZ8051MLL_H
+
+#include
+
+/**@{*/
+
+/* Registers */
+
+#define PHY_REG_AFECTRL 0x11
+#define PHY_REG_RXERCTR 0x15
+#define PHY_REG_STRAPOVRD 0x16
+#define PHY_REG_STRAPSTAT 0x17
+#define PHY_REG_ECR 0x18
+
+#define PHY_REG_ICSR 0x1B
+
+#define PHY_REG_LINKMD 0x1D
+
+#define PHY_REG_CR1 0x1E
+#define PHY_REG_CR2 0x1E
+
+/**@}*/
+
+
+#endif /* LIBOPENCM3_PHY_KSZ8051MLL_H__ */
diff --git a/include/libopencm3/stm32/ethernet.h b/include/libopencm3/stm32/ethernet.h
new file mode 100644
index 00000000..73ff7287
--- /dev/null
+++ b/include/libopencm3/stm32/ethernet.h
@@ -0,0 +1,27 @@
+/* This provides unification of code over STM32F subfamilies */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+#if defined(STM32F1)
+# include
+#elif defined(STM32F4)
+# include
+#else
+# error "stm32 family not defined."
+#endif
+
diff --git a/lib/ethernet/mac.c b/lib/ethernet/mac.c
new file mode 100644
index 00000000..3b7db129
--- /dev/null
+++ b/lib/ethernet/mac.c
@@ -0,0 +1,43 @@
+/** @defgroup ethernet_mac_file MAC Generic Drivers
+ *
+ * @ingroup ETH
+ *
+ * @brief Ethernet MAC Generic Drivers
+ *
+ * @version 1.0.0
+ * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian
+ *
+ * @date 1 September 2013
+ *
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2013 Frantisek Burian
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+#include
+#include
+
+/**@{*/
+
+
+/*---------------------------------------------------------------------------*/
+
+/**@}*/
diff --git a/lib/ethernet/mac_stm32fxx7.c b/lib/ethernet/mac_stm32fxx7.c
new file mode 100644
index 00000000..67623983
--- /dev/null
+++ b/lib/ethernet/mac_stm32fxx7.c
@@ -0,0 +1,378 @@
+/** @defgroup ethernet_mac_stm32fxx7_file MAC STM32Fxx7
+ *
+ * @ingroup ETH
+ *
+ * @brief Ethernet MAC STM32Fxx7 Drivers
+ *
+ * @version 1.0.0
+ * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian
+ *
+ * @date 1 September 2013
+ *
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2013 Frantisek Burian
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+/**@{*/
+
+uint32_t TxBD;
+uint32_t RxBD;
+
+/*---------------------------------------------------------------------------*/
+/** @brief Set MAC to the PHY
+ *
+ * @param[in] mac uint8_t* Desired MAC
+ */
+void eth_set_mac(uint8_t *mac)
+{
+ ETH_MACAHR(0) = ((uint32_t)mac[5] << 8) | (uint32_t)mac[4] |
+ ETH_MACA0HR_MACA0H;
+ ETH_MACALR(0) = ((uint32_t)mac[3] << 24) | ((uint32_t)mac[2] << 16) |
+ ((uint32_t)mac[1] << 8) | mac[0];
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Initialize descriptors
+ *
+ * @param[in] buf uint8_t* Buffer for the descriptors
+ * @param[in] nTx uint32_t Count of Transmit Descriptors
+ * @param[in] nRx uint32_t Count of Receive Descriptors
+ * @param[in] cTx uint32_t Bytes in each Transmit Descriptor
+ * @param[in] cRx uint32_t Bytes in each Receive Descriptor
+ * @param[in] isext bool true, if extended descriptors should be used
+ */
+void eth_desc_init(uint8_t *buf, uint32_t nTx, uint32_t nRx, uint32_t cTx,
+ uint32_t cRx, bool isext)
+{
+ memset(buf, 0, nTx * cTx + nRx * cRx);
+
+ uint32_t bd = (uint32_t)buf;
+ uint32_t sz = isext ? ETH_DES_EXT_SIZE : ETH_DES_STD_SIZE;
+
+ /* enable / disable extended frames */
+ if (isext) {
+ ETH_DMABMR |= ETH_DMABMR_EDFE;
+ } else {
+ ETH_DMABMR &= ~ETH_DMABMR_EDFE;
+ }
+
+ TxBD = bd;
+ while (--nTx > 0) {
+ ETH_DES0(bd) = ETH_TDES0_TCH;
+ ETH_DES2(bd) = bd + sz;
+ ETH_DES3(bd) = bd + sz + cTx;
+ bd = ETH_DES3(bd);
+ }
+
+ ETH_DES0(bd) = ETH_TDES0_TCH;
+ ETH_DES2(bd) = bd + sz;
+ ETH_DES3(bd) = TxBD;
+ bd += sz + cTx;
+
+ RxBD = bd;
+ while (--nRx > 0) {
+ ETH_DES0(bd) = ETH_RDES0_OWN;
+ ETH_DES1(bd) = ETH_RDES1_RCH | cRx;
+ ETH_DES2(bd) = bd + sz;
+ ETH_DES3(bd) = bd + sz + cRx;
+ bd = ETH_DES3(bd);
+ }
+
+ ETH_DES0(bd) = ETH_RDES0_OWN;
+ ETH_DES1(bd) = ETH_RDES1_RCH | cRx;
+ ETH_DES2(bd) = bd + sz;
+ ETH_DES3(bd) = RxBD;
+
+ ETH_DMARDLAR = (uint32_t) RxBD;
+ ETH_DMATDLAR = (uint32_t) TxBD;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Transmit packet
+ *
+ * @param[in] ppkt uint8_t* Pointer to the beginning of the packet
+ * @param[in] n uint32_t Size of the packet
+ * @returns bool true, if success
+ */
+bool eth_tx(uint8_t *ppkt, uint32_t n)
+{
+ if (ETH_DES0(TxBD) & ETH_TDES0_OWN) {
+ return false;
+ }
+
+ memcpy((void *)ETH_DES2(TxBD), ppkt, n);
+
+ ETH_DES1(TxBD) = n & ETH_TDES1_TBS1;
+ ETH_DES0(TxBD) |= ETH_TDES0_LS | ETH_TDES0_FS | ETH_TDES0_OWN;
+ TxBD = ETH_DES3(TxBD);
+
+ if (ETH_DMASR & ETH_DMASR_TBUS) {
+ ETH_DMASR = ETH_DMASR_TBUS;
+ ETH_DMATPDR = 0;
+ }
+
+ return true;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Receive packet
+ *
+ * @param[inout] ppkt uint8_t* Pointer to the data buffer where to store data
+ * @param[inout] len uint32_t* Pointer to the variable with the packet length
+ * @param[in] maxlen uint32_t Maximum length of the packet
+ * @returns bool true, if the buffer contains readed packet data
+ */
+bool eth_rx(uint8_t *ppkt, uint32_t *len, uint32_t maxlen)
+{
+ bool fs = false;
+ bool ls = false;
+ bool overrun = false;
+ uint32_t l = 0;
+
+ while (!(ETH_DES0(RxBD) & ETH_RDES0_OWN) && !ls) {
+ l = (ETH_DES0(RxBD) & ETH_RDES0_FL) >> ETH_RDES0_FL_SHIFT;
+
+ fs |= ETH_DES0(RxBD) & ETH_RDES0_FS;
+ ls |= ETH_DES0(RxBD) & ETH_RDES0_LS;
+ /* frame buffer overrun ?*/
+ overrun |= fs && (maxlen < l);
+
+ if (fs && !overrun) {
+ memcpy(ppkt, (void *)ETH_DES2(RxBD), l);
+ ppkt += l;
+ *len += l;
+ maxlen -= l;
+ }
+
+ ETH_DES0(RxBD) = ETH_RDES0_OWN;
+ RxBD = ETH_DES3(RxBD);
+ }
+
+ if (ETH_DMASR & ETH_DMASR_RBUS) {
+ ETH_DMASR = ETH_DMASR_RBUS;
+ ETH_DMARPDR = 0;
+ }
+
+ return fs && ls && !overrun;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Start the Ethernet DMA processing
+ */
+void eth_start(void)
+{
+ ETH_MACCR |= ETH_MACCR_TE;
+ ETH_DMAOMR |= ETH_DMAOMR_FTF;
+ ETH_MACCR |= ETH_MACCR_RE;
+
+ ETH_DMAOMR |= ETH_DMAOMR_ST;
+ ETH_DMAOMR |= ETH_DMAOMR_SR;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Initialize ethernet
+ *
+ * This function will initialize ethernet, set up clocks, and initialize DMA.
+ *
+ * @param[in] clock enum eth_clk Core clock speed
+ */
+void eth_init(enum eth_clk clock)
+{
+ ETH_MACMIIAR = clock;
+ phy_reset();
+
+ ETH_MACCR = ETH_MACCR_CSTF | ETH_MACCR_FES | ETH_MACCR_DM |
+ ETH_MACCR_APCS | ETH_MACCR_RD;
+ ETH_MACFFR = ETH_MACFFR_RA | ETH_MACFFR_PM;
+ ETH_MACHTHR = 0; /* pass all frames */
+ ETH_MACHTLR = 0;
+ ETH_MACFCR = (0x100 << ETH_MACFCR_PT_SHIFT);
+ ETH_MACVLANTR = 0;
+ ETH_DMAOMR = ETH_DMAOMR_DTCEFD | ETH_DMAOMR_RSF | ETH_DMAOMR_DFRF |
+ ETH_DMAOMR_TSF | ETH_DMAOMR_FEF | ETH_DMAOMR_OSF;
+ ETH_DMABMR = ETH_DMABMR_AAB | ETH_DMABMR_FB |
+ (32 << ETH_DMABMR_RDP_SHIFT) | (32 << ETH_DMABMR_PBL_SHIFT) |
+ ETH_DMABMR_PM_2_1 | ETH_DMABMR_USP;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Enable the Ethernet IRQ
+ *
+ * @param[in] reason uint32_t Which irq will be enabled
+ */
+void eth_irq_enable(uint32_t reason)
+{
+ ETH_DMAIER |= reason;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Disable the Ethernet IRQ
+ *
+ * @param[in] reason uint32_t Which irq will be disabled
+ */
+void eth_irq_disable(uint32_t reason)
+{
+ ETH_DMAIER &= ~reason;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Check if IRQ is pending
+ *
+ * @param[in] reason uint32_t Which irq type has to be tested
+ * @returns bool true, if IRQ is pending
+ */
+bool eth_irq_is_pending(uint32_t reason)
+{
+ return (ETH_DMASR & reason) != 0;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Check if IRQ is pending, and acknowledge it
+ *
+ * @param[in] reason uint32_t Which irq type has to be tested
+ * @returns bool true, if IRQ is pending
+ */
+bool eth_irq_ack_pending(uint32_t reason)
+{
+ reason &= ETH_DMASR;
+ ETH_DMASR = reason;
+ return reason != 0;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Enable checksum offload feature
+ *
+ * This function will enable the Checksum offload feature for all of the
+ * transmit descriptors. Note to use this feature, descriptors must be in
+ * extended format.
+ */
+void eth_enable_checksum_offload(void)
+{
+ uint32_t tab = TxBD;
+ do {
+ ETH_DES0(tab) |= ETH_TDES0_CIC_IPPLPH;
+ tab = ETH_DES3(tab);
+ }
+ while (tab != TxBD);
+
+ ETH_MACCR |= ETH_MACCR_IPCO;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Process pending SMI transaction and wait to be done.
+ */
+static void eth_smi_transact(void)
+{
+ /* Begin transaction. */
+ ETH_MACMIIAR |= ETH_MACMIIAR_MB;
+
+ /* Wait for not busy. */
+ while (ETH_MACMIIAR & ETH_MACMIIAR_MB);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Write 16-bit register to the PHY
+ *
+ * @param[in] phy uint8_t ID of the PHY (defaults to 1)
+ * @param[in] reg uint8_t Register address
+ * @param[in] data uint16_t Data to write
+ */
+void eth_smi_write(uint8_t phy, uint8_t reg, uint16_t data)
+{
+ /* Write operation MW=1*/
+ ETH_MACMIIAR = (ETH_MACMIIAR & ETH_MACMIIAR_CR) | /* save clocks */
+ (phy << ETH_MACMIIAR_PA_SHIFT) |
+ (reg << ETH_MACMIIAR_MR_SHIFT) |
+ ETH_MACMIIAR_MW;
+
+ ETH_MACMIIDR = data & ETH_MACMIIDR_MD;
+
+ eth_smi_transact();
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Read the 16-bit register from the PHY
+ *
+ * @param[in] phy uint8_t ID of the PHY (defaults to 1)
+ * @param[in] reg uint8_t Register address
+ * @returns uint16_t Readed data
+ */
+uint16_t eth_smi_read(uint8_t phy, uint8_t reg)
+{
+ /* Read operation MW=0*/
+ ETH_MACMIIAR = (ETH_MACMIIAR & ETH_MACMIIAR_CR) | /* save clocks */
+ (phy << ETH_MACMIIAR_PA_SHIFT) |
+ (reg << ETH_MACMIIAR_MR_SHIFT);
+
+ eth_smi_transact();
+
+ return (uint16_t)(ETH_MACMIIDR & ETH_MACMIIDR_MD);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Process the bit-operation on PHY register
+ *
+ * @param[in] phy uint8_t ID of the PHY (defaults to 1)
+ * @param[in] reg uint8_t Register address
+ * @param[in] bits uint16_t Bits that have to be set (or'ed)
+ * @param[in] mask uint16_t Bits that have to be clear (and'ed)
+ */
+void eth_smi_bit_op(uint8_t phy, uint8_t reg, uint16_t bits, uint16_t mask)
+{
+ uint16_t val = eth_smi_read(phy, reg);
+ eth_smi_write(phy, reg, (val & mask) | bits);
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Clear bits in the register
+ *
+ * @param[in] phy uint8_t ID of the PHY (defaults to 1)
+ * @param[in] reg uint8_t Register address
+ * @param[in] clearbits uint16_t Bits that have to be cleared
+ */
+void eth_smi_bit_clear(uint8_t phy, uint8_t reg, uint16_t clearbits)
+{
+ uint16_t val = eth_smi_read(phy, reg);
+ eth_smi_write(phy, reg, val & (uint16_t)~(clearbits));
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Set bits in the register
+ *
+ * @param[in] phy uint8_t ID of the PHY (defaults to 1)
+ * @param[in] reg uint8_t Register address
+ * @param[in] bits uint16_t Bits that have to be set (or'ed)
+ */
+void eth_smi_bit_set(uint8_t phy, uint8_t reg, uint16_t setbits)
+{
+ uint16_t val = eth_smi_read(phy, reg);
+ eth_smi_write(phy, reg, val | setbits);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/**@}*/
diff --git a/lib/ethernet/phy.c b/lib/ethernet/phy.c
new file mode 100644
index 00000000..1f9197e7
--- /dev/null
+++ b/lib/ethernet/phy.c
@@ -0,0 +1,64 @@
+/** @defgroup ethernet_phy_file PHY Generic Drivers
+ *
+ * @ingroup ETH
+ *
+ * @brief Ethernet PHY Generic Drivers
+ *
+ * @version 1.0.0
+ * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian
+ *
+ * @date 1 September 2013
+ *
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2013 Frantisek Burian
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+#include
+#include
+
+/**@{*/
+
+/*---------------------------------------------------------------------------*/
+/** @brief Is the link up ?
+ *
+ * @returns bool true, if link is up
+ */
+bool phy_link_isup(void)
+{
+ return eth_smi_read(1, PHY_REG_BSR) & PHY_REG_BSR_UP;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Reset the PHY
+ *
+ * Reset the PHY chip and wait for done
+ */
+void phy_reset(void)
+{
+ eth_smi_write(1, PHY_REG_BCR, PHY_REG_BCR_RESET);
+
+ while (eth_smi_read(1, PHY_REG_BCR) & PHY_REG_BCR_RESET);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/**@}*/
diff --git a/lib/ethernet/phy_ksz8051mll.c b/lib/ethernet/phy_ksz8051mll.c
new file mode 100644
index 00000000..407c5a4d
--- /dev/null
+++ b/lib/ethernet/phy_ksz8051mll.c
@@ -0,0 +1,89 @@
+/** @defgroup ethernet_phy_ksz8051mll_file PHY KSZ8051MLL
+ *
+ * @ingroup ETH
+ *
+ * @brief Ethernet PHY STM32Fxx7 Drivers
+ *
+ * @version 1.0.0
+ * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian
+ *
+ * @date 1 September 2013
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2013 Frantisek Burian
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+#include
+#include
+#include
+
+
+/**@{*/
+
+/*---------------------------------------------------------------------------*/
+/** @brief Get the current link status
+ *
+ * Retrieve the link speed and duplex status of the link.
+ *
+ * @returns ::phy_status Link status
+ */
+enum phy_status phy_link_status(void)
+{
+ return eth_smi_read(1, PHY_REG_CR1) & 0x07;
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Force autonegotiation
+ *
+ * Force the autonegotiation and set link speed and duplex mode of the link
+ *
+ * @param[in] mode enum phy_status Desired link status
+ */
+void phy_autoneg_force(enum phy_status mode)
+{
+ uint16_t bst = 0;
+
+ if ((mode == LINK_FD_10M) || (mode == LINK_FD_100M) ||
+ (mode == LINK_FD_1000M) || (mode == LINK_FD_10000M)) {
+ bst |= PHY_REG_BCR_FD;
+ }
+
+ if ((mode == LINK_FD_100M) || (mode == LINK_FD_100M)) {
+ bst |= PHY_REG_BCR_100M;
+ }
+
+ eth_smi_bit_op(1, PHY_REG_BCR, bst,
+ ~(PHY_REG_BCR_AN | PHY_REG_BCR_100M | PHY_REG_BCR_FD));
+}
+
+/*---------------------------------------------------------------------------*/
+/** @brief Enable the autonegotiation
+ *
+ * Enable the autonegotiation of the link speed and duplex mode
+ */
+void phy_autoneg_enable(void)
+{
+ eth_smi_bit_set(1, PHY_REG_BCR, PHY_REG_BCR_AN | PHY_REG_BCR_ANRST);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/**@}*/
diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile
index 4d2843be..a21bbf9f 100644
--- a/lib/stm32/f4/Makefile
+++ b/lib/stm32/f4/Makefile
@@ -50,6 +50,9 @@ OBJS += crc_common_all.o dac_common_all.o dma_common_f24.o \
OBJS += usb.o usb_standard.o usb_control.o usb_fx07_common.o \
usb_f107.o usb_f207.o
+OBJS += mac.o phy.o mac_stm32fxx7.o phy_ksz8051mll.o
+
VPATH += ../../usb:../:../../cm3:../common
+VPATH += ../../ethernet
include ../../Makefile.include