]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c
Add missing +TCP code.
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / portable / NetworkInterface / STM32Fxx / NetworkInterface.c
index d294fe92f45075becb092112efffc58c8ff74bc0..9d7a7ee2f8eab42f9d9ce4d6317b300ed6bdf1ed 100644 (file)
 #include "FreeRTOS_DNS.h"\r
 #include "NetworkBufferManagement.h"\r
 #include "NetworkInterface.h"\r
+#include "phyHandling.h"\r
 \r
 /* ST includes. */\r
-#include "stm32f4xx_hal.h"\r
-\r
-#ifndef        BMSR_LINK_STATUS\r
-       #define BMSR_LINK_STATUS            0x0004UL\r
-#endif\r
-\r
-#ifndef        PHY_LS_HIGH_CHECK_TIME_MS\r
-       /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not\r
-       receiving packets. */\r
-       #define PHY_LS_HIGH_CHECK_TIME_MS       15000\r
-#endif\r
-\r
-#ifndef        PHY_LS_LOW_CHECK_TIME_MS\r
-       /* Check if the LinkSStatus in the PHY is still low every second. */\r
-       #define PHY_LS_LOW_CHECK_TIME_MS        1000\r
+#ifdef STM32F7xx\r
+       #include "stm32f7xx_hal.h"\r
+#else\r
+       #include "stm32f4xx_hal.h"\r
 #endif\r
 \r
 /* Interrupt events to process.  Currently only the Rx event is processed\r
@@ -110,75 +100,7 @@ expansion. */
          ETH_DMA_IT_FBE | ETH_DMA_IT_RWT | ETH_DMA_IT_RPS | ETH_DMA_IT_RBU | ETH_DMA_IT_R | \\r
          ETH_DMA_IT_TU | ETH_DMA_IT_RO | ETH_DMA_IT_TJT | ETH_DMA_IT_TPS | ETH_DMA_IT_T )\r
 \r
-/* Naming and numbering of PHY registers. */\r
-#define PHY_REG_00_BMCR                        0x00    /* Basic Mode Control Register. */\r
-#define PHY_REG_01_BMSR                        0x01    /* Basic Mode Status Register. */\r
-#define PHY_REG_02_PHYSID1             0x02    /* PHYS ID 1 */\r
-#define PHY_REG_03_PHYSID2             0x03    /* PHYS ID 2 */\r
-#define PHY_REG_04_ADVERTISE   0x04    /* Advertisement control reg */\r
-\r
-#define PHY_ID_LAN8720         0x0007c0f0\r
-#define PHY_ID_DP83848I                0x20005C90\r
-\r
-#ifndef USE_STM324xG_EVAL\r
-       #define USE_STM324xG_EVAL       1\r
-#endif\r
-\r
-#if( USE_STM324xG_EVAL == 0 )\r
-       #define EXPECTED_PHY_ID                 PHY_ID_LAN8720\r
-       #define PHY_REG_1F_PHYSPCS              0x1F    /* 31 RW PHY Special Control Status */\r
-       /* Use 3 bits in register 31 */\r
-       #define PHYSPCS_SPEED_MASK              0x0C\r
-       #define PHYSPCS_SPEED_10                0x04\r
-       #define PHYSPCS_SPEED_100               0x08\r
-       #define PHYSPCS_FULL_DUPLEX             0x10\r
-#else\r
-       #define EXPECTED_PHY_ID         PHY_ID_DP83848I\r
-\r
-       #define PHY_REG_10_PHY_SR               0x10    /* PHY status register Offset */\r
-       #define PHY_REG_19_PHYCR                0x19    /* 25 RW PHY Control Register */\r
-#endif\r
-\r
-/* Some defines used internally here to indicate preferences about speed, MDIX\r
-(wired direct or crossed), and duplex (half or full). */\r
-#define        PHY_SPEED_10       1\r
-#define        PHY_SPEED_100      2\r
-#define        PHY_SPEED_AUTO     (PHY_SPEED_10|PHY_SPEED_100)\r
-\r
-#define        PHY_MDIX_DIRECT    1\r
-#define        PHY_MDIX_CROSSED   2\r
-#define        PHY_MDIX_AUTO      (PHY_MDIX_CROSSED|PHY_MDIX_DIRECT)\r
-\r
-#define        PHY_DUPLEX_HALF    1\r
-#define        PHY_DUPLEX_FULL    2\r
-#define        PHY_DUPLEX_AUTO    (PHY_DUPLEX_FULL|PHY_DUPLEX_HALF)\r
 \r
-#define PHY_AUTONEGO_COMPLETE    ((uint16_t)0x0020)  /*!< Auto-Negotiation process completed   */\r
-\r
-/*\r
- * Description of all capabilities that can be advertised to\r
- * the peer (usually a switch or router).\r
- */\r
-#define ADVERTISE_CSMA                 0x0001          /* Only selector supported. */\r
-#define ADVERTISE_10HALF               0x0020          /* Try for 10mbps half-duplex. */\r
-#define ADVERTISE_10FULL               0x0040          /* Try for 10mbps full-duplex. */\r
-#define ADVERTISE_100HALF              0x0080          /* Try for 100mbps half-duplex. */\r
-#define ADVERTISE_100FULL              0x0100          /* Try for 100mbps full-duplex. */\r
-\r
-#define ADVERTISE_ALL                  ( ADVERTISE_10HALF | ADVERTISE_10FULL | \\r
-                                                                 ADVERTISE_100HALF | ADVERTISE_100FULL)\r
-\r
-/*\r
- * Value for the 'PHY_REG_00_BMCR', the PHY's Basic Mode Control Register.\r
- */\r
-#define BMCR_FULLDPLX                  0x0100          /* Full duplex. */\r
-#define BMCR_ANRESTART                 0x0200          /* Auto negotiation restart. */\r
-#define BMCR_ANENABLE                  0x1000          /* Enable auto negotiation. */\r
-#define BMCR_SPEED100                  0x2000          /* Select 100Mbps. */\r
-#define BMCR_RESET                             0x8000          /* Reset the PHY. */\r
-\r
-#define PHYCR_MDIX_EN                  0x8000          /* Enable Auto MDIX. */\r
-#define PHYCR_MDIX_FORCE               0x4000          /* Force MDIX crossed. */\r
 \r
 #define ipFRAGMENT_OFFSET_BIT_MASK             ( ( uint16_t ) 0x0fff ) /* The bits in the two byte IP header field that make up the fragment offset value. */\r
 \r
@@ -223,6 +145,18 @@ FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
        #define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )\r
 #endif\r
 \r
+/* Two choices must be made: RMII versus MII,\r
+and the index of the PHY in use ( between 0 and 31 ). */\r
+#ifndef ipconfigUSE_RMII\r
+       #ifdef STM32F7xx\r
+               #define ipconfigUSE_RMII        1\r
+       #else\r
+               #define ipconfigUSE_RMII        0\r
+       #endif /* STM32F7xx */\r
+#endif /* ipconfigUSE_RMII */\r
+\r
+\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
@@ -263,43 +197,30 @@ static void prvDMATxDescListInit( void );
  */\r
 static void prvDMARxDescListInit( void );\r
 \r
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
-       /* After packets have been sent, the network\r
-       buffers will be released. */\r
-       static void vClearTXBuffers( void );\r
-#endif /* ipconfigZERO_COPY_TX_DRIVER */\r
+/* After packets have been sent, the network\r
+buffers will be released. */\r
+static void vClearTXBuffers( void );\r
 \r
 /*-----------------------------------------------------------*/\r
 \r
-typedef struct _PhyProperties_t\r
-{\r
-       uint8_t speed;\r
-       uint8_t mdix;\r
-       uint8_t duplex;\r
-       uint8_t spare;\r
-} PhyProperties_t;\r
-\r
 /* Bit map of outstanding ETH interrupt events for processing.  Currently only\r
 the Rx interrupt is handled, although code is included for other events to\r
 enable future expansion. */\r
 static volatile uint32_t ulISREvents;\r
 \r
-/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */\r
-static uint32_t ulPHYLinkStatus = 0;\r
-\r
 #if( ipconfigUSE_LLMNR == 1 )\r
        static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };\r
 #endif\r
 \r
+static EthernetPhy_t xPhyObject;\r
+\r
 /* Ethernet handle. */\r
 static ETH_HandleTypeDef xETH;\r
 \r
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
-       /* xTXDescriptorSemaphore is a counting semaphore with\r
-       a maximum count of ETH_TXBUFNB, which is the number of\r
-       DMA TX descriptors. */\r
-       static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;\r
-#endif /* ipconfigZERO_COPY_TX_DRIVER */\r
+/* xTXDescriptorSemaphore is a counting semaphore with\r
+a maximum count of ETH_TXBUFNB, which is the number of\r
+DMA TX descriptors. */\r
+static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;\r
 \r
 /*\r
  * Note: it is adviced to define both\r
@@ -314,14 +235,29 @@ static ETH_HandleTypeDef xETH;
  * TX buffers are allocated in a zero-copy driver.\r
  */\r
 /* MAC buffers: ---------------------------------------------------------*/\r
-__ALIGN_BEGIN ETH_DMADescTypeDef  DMARxDscrTab[ ETH_RXBUFNB ] __ALIGN_END;/* Ethernet Rx MA Descriptor */\r
+\r
+/* Put the DMA descriptors in '.first_data'.\r
+This is important for STM32F7, which has an L1 data cache.\r
+The first 64KB of the SRAM is not cached. */\r
+\r
+/* Ethernet Rx MA Descriptor */\r
+__attribute__ ((aligned (32)))\r
+__attribute__ ((section(".first_data")))\r
+       ETH_DMADescTypeDef  DMARxDscrTab[ ETH_RXBUFNB ];\r
+\r
 #if( ipconfigZERO_COPY_RX_DRIVER == 0 )\r
-       __ALIGN_BEGIN uint8_t Rx_Buff[ ETH_RXBUFNB ][ ETH_RX_BUF_SIZE ] __ALIGN_END; /* Ethernet Receive Buffer */\r
+       /* Ethernet Receive Buffer */\r
+       __ALIGN_BEGIN uint8_t Rx_Buff[ ETH_RXBUFNB ][ ETH_RX_BUF_SIZE ] __ALIGN_END;\r
 #endif\r
 \r
-__ALIGN_BEGIN ETH_DMADescTypeDef  DMATxDscrTab[ ETH_TXBUFNB ] __ALIGN_END;/* Ethernet Tx DMA Descriptor */\r
+/* Ethernet Tx DMA Descriptor */\r
+__attribute__ ((aligned (32)))\r
+__attribute__ ((section(".first_data")))\r
+       ETH_DMADescTypeDef  DMATxDscrTab[ ETH_TXBUFNB ];\r
+\r
 #if( ipconfigZERO_COPY_TX_DRIVER == 0 )\r
-       __ALIGN_BEGIN uint8_t Tx_Buff[ ETH_TXBUFNB ][ ETH_TX_BUF_SIZE ] __ALIGN_END; /* Ethernet Transmit Buffer */\r
+       /* Ethernet Transmit Buffer */\r
+       __ALIGN_BEGIN uint8_t Tx_Buff[ ETH_TXBUFNB ][ ETH_TX_BUF_SIZE ] __ALIGN_END;\r
 #endif\r
 \r
 #if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
@@ -330,12 +266,6 @@ __ALIGN_BEGIN ETH_DMADescTypeDef  DMATxDscrTab[ ETH_TXBUFNB ] __ALIGN_END;/* Eth
        static __IO ETH_DMADescTypeDef  *DMATxDescToClear;\r
 #endif\r
 \r
-/* Value to be written into the 'Basic mode Control Register'. */\r
-static uint32_t ulBCRvalue;\r
-\r
-/* Value to be written into the 'Advertisement Control Register'. */\r
-static uint32_t ulACRValue;\r
-\r
 /* ucMACAddress as it appears in main.c */\r
 extern const uint8_t ucMACAddress[ 6 ];\r
 \r
@@ -348,13 +278,13 @@ static TaskHandle_t xEMACTaskHandle = NULL;
 const PhyProperties_t xPHYProperties =\r
 {\r
        #if( ipconfigETHERNET_AN_ENABLE != 0 )\r
-               .speed = PHY_SPEED_AUTO,\r
-               .duplex = PHY_DUPLEX_AUTO,\r
+               .ucSpeed = PHY_SPEED_AUTO,\r
+               .ucDuplex = PHY_DUPLEX_AUTO,\r
        #else\r
                #if( ipconfigETHERNET_USE_100MB != 0 )\r
-                       .speed = PHY_SPEED_100,\r
+                       .ucSpeed = PHY_SPEED_100,\r
                #else\r
-                       .speed = PHY_SPEED_10,\r
+                       .ucSpeed = PHY_SPEED_10,\r
                #endif\r
 \r
                #if( ipconfigETHERNET_USE_FULL_DUPLEX != 0 )\r
@@ -365,11 +295,11 @@ const PhyProperties_t xPHYProperties =
        #endif\r
 \r
        #if( ipconfigETHERNET_AN_ENABLE != 0 ) && ( ipconfigETHERNET_AUTO_CROSS_ENABLE != 0 )\r
-               .mdix = PHY_MDIX_AUTO,\r
+               .ucMDI_X = PHY_MDIX_AUTO,\r
        #elif( ipconfigETHERNET_CROSSED_LINK != 0 )\r
-               .mdix = PHY_MDIX_CROSSED,\r
+               .ucMDI_X = PHY_MDIX_CROSSED,\r
        #else\r
-               .mdix = PHY_MDIX_DIRECT,\r
+               .ucMDI_X = PHY_MDIX_DIRECT,\r
        #endif\r
 };\r
 \r
@@ -390,46 +320,45 @@ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
-       void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef *heth )\r
-       {\r
-       BaseType_t xHigherPriorityTaskWoken = pdFALSE;\r
-\r
-               /* This call-back is only useful in case packets are being sent\r
-               zero-copy.  Once they're sent, the buffers will be released\r
-               by the function vClearTXBuffers(). */\r
-               ulISREvents |= EMAC_IF_TX_EVENT;\r
-               /* Wakeup the prvEMACHandlerTask. */\r
-               if( xEMACTaskHandle != NULL )\r
-               {\r
-                       vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );\r
-                       portYIELD_FROM_ISR( xHigherPriorityTaskWoken );\r
-               }\r
+void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef *heth )\r
+{\r
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;\r
 \r
+       /* This call-back is only useful in case packets are being sent\r
+       zero-copy.  Once they're sent, the buffers will be released\r
+       by the function vClearTXBuffers(). */\r
+       ulISREvents |= EMAC_IF_TX_EVENT;\r
+       /* Wakeup the prvEMACHandlerTask. */\r
+       if( xEMACTaskHandle != NULL )\r
+       {\r
+               vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );\r
+               portYIELD_FROM_ISR( xHigherPriorityTaskWoken );\r
        }\r
-#endif /* ipconfigZERO_COPY_TX_DRIVER */\r
 \r
+}\r
 /*-----------------------------------------------------------*/\r
 \r
+static void vClearTXBuffers()\r
+{\r
+__IO ETH_DMADescTypeDef  *txLastDescriptor = xETH.TxDesc;\r
+size_t uxCount = ( ( UBaseType_t ) ETH_TXBUFNB ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );\r
 #if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
-       static void vClearTXBuffers()\r
-       {\r
-       __IO ETH_DMADescTypeDef  *txLastDescriptor = xETH.TxDesc;\r
        NetworkBufferDescriptor_t *pxNetworkBuffer;\r
        uint8_t *ucPayLoad;\r
-       size_t uxCount = ( ( UBaseType_t ) ETH_TXBUFNB ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );\r
+#endif\r
 \r
-               /* This function is called after a TX-completion interrupt.\r
-               It will release each Network Buffer used in xNetworkInterfaceOutput().\r
-               'uxCount' represents the number of descriptors given to DMA for transmission.\r
-               After sending a packet, the DMA will clear the 'ETH_DMATXDESC_OWN' bit. */\r
-               while( ( uxCount > 0 ) && ( ( DMATxDescToClear->Status & ETH_DMATXDESC_OWN ) == 0 ) )\r
+       /* This function is called after a TX-completion interrupt.\r
+       It will release each Network Buffer used in xNetworkInterfaceOutput().\r
+       'uxCount' represents the number of descriptors given to DMA for transmission.\r
+       After sending a packet, the DMA will clear the 'ETH_DMATXDESC_OWN' bit. */\r
+       while( ( uxCount > 0 ) && ( ( DMATxDescToClear->Status & ETH_DMATXDESC_OWN ) == 0 ) )\r
+       {\r
+               if( ( DMATxDescToClear == txLastDescriptor ) && ( uxCount != ETH_TXBUFNB ) )\r
+               {\r
+                       break;\r
+               }\r
+               #if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
                {\r
-                       if( ( DMATxDescToClear == txLastDescriptor ) && ( uxCount != ETH_TXBUFNB ) )\r
-                       {\r
-                               break;\r
-                       }\r
-\r
                        ucPayLoad = ( uint8_t * )DMATxDescToClear->Buffer1Addr;\r
 \r
                        if( ucPayLoad != NULL )\r
@@ -441,15 +370,16 @@ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
                                }\r
                                DMATxDescToClear->Buffer1Addr = ( uint32_t )0u;\r
                        }\r
+               }\r
+               #endif /* ipconfigZERO_COPY_TX_DRIVER */\r
 \r
-                       DMATxDescToClear = ( ETH_DMADescTypeDef * )( DMATxDescToClear->Buffer2NextDescAddr );\r
+               DMATxDescToClear = ( ETH_DMADescTypeDef * )( DMATxDescToClear->Buffer2NextDescAddr );\r
 \r
-                       uxCount--;\r
-                       /* Tell the counting semaphore that one more TX descriptor is available. */\r
-                       xSemaphoreGive( xTXDescriptorSemaphore );\r
-               }\r
+               uxCount--;\r
+               /* Tell the counting semaphore that one more TX descriptor is available. */\r
+               xSemaphoreGive( xTXDescriptorSemaphore );\r
        }\r
-#endif /* ipconfigZERO_COPY_TX_DRIVER */\r
+}\r
 /*-----------------------------------------------------------*/\r
 \r
 BaseType_t xNetworkInterfaceInitialise( void )\r
@@ -459,15 +389,11 @@ BaseType_t xResult;
 \r
        if( xEMACTaskHandle == NULL )\r
        {\r
-               #if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
+               if( xTXDescriptorSemaphore == NULL )\r
                {\r
-                       if( xTXDescriptorSemaphore == NULL )\r
-                       {\r
-                               xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ETH_TXBUFNB, ( UBaseType_t ) ETH_TXBUFNB );\r
-                               configASSERT( xTXDescriptorSemaphore );\r
-                       }\r
+                       xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ETH_TXBUFNB, ( UBaseType_t ) ETH_TXBUFNB );\r
+                       configASSERT( xTXDescriptorSemaphore );\r
                }\r
-               #endif /* ipconfigZERO_COPY_TX_DRIVER */\r
 \r
                /* Initialise ETH */\r
 \r
@@ -475,7 +401,8 @@ BaseType_t xResult;
                xETH.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;\r
                xETH.Init.Speed = ETH_SPEED_100M;\r
                xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;\r
-               xETH.Init.PhyAddress = 1;\r
+               /* Value of PhyAddress doesn't matter, will be probed for. */\r
+               xETH.Init.PhyAddress = 0;\r
 \r
                xETH.Init.MACAddr = ( uint8_t *) ucMACAddress;\r
                xETH.Init.RxMode = ETH_RXINTERRUPT_MODE;\r
@@ -485,7 +412,16 @@ BaseType_t xResult;
                by the peripheral. */\r
                xETH.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;\r
 \r
-               xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_MII;\r
+               #if( ipconfigUSE_RMII != 0 )\r
+               {\r
+                       xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;\r
+               }\r
+               #else\r
+               {\r
+                       xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_MII;\r
+               }\r
+               #endif /* ipconfigUSE_RMII */\r
+\r
                hal_eth_init_status = HAL_ETH_Init( &xETH );\r
 \r
                /* Only for inspection by debugger. */\r
@@ -499,12 +435,8 @@ BaseType_t xResult;
                memset( &DMATxDscrTab, '\0', sizeof( DMATxDscrTab ) );\r
                memset( &DMARxDscrTab, '\0', sizeof( DMARxDscrTab ) );\r
 \r
-               #if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
-               {\r
-                       /* Initialize Tx Descriptors list: Chain Mode */\r
-                       DMATxDescToClear = DMATxDscrTab;\r
-               }\r
-               #endif /* ipconfigZERO_COPY_TX_DRIVER */\r
+               /* Initialize Tx Descriptors list: Chain Mode */\r
+               DMATxDescToClear = DMATxDscrTab;\r
 \r
                /* Initialise TX-descriptors. */\r
                prvDMATxDescListInit();\r
@@ -529,7 +461,7 @@ BaseType_t xResult;
                xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );\r
        } /* if( xEMACTaskHandle == NULL ) */\r
 \r
-       if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )\r
+       if( xPhyObject.ulLinkStatusMask != 0 )\r
        {\r
                xETH.Instance->DMAIER |= ETH_DMA_ALL_INTS;\r
                xResult = pdPASS;\r
@@ -538,7 +470,7 @@ BaseType_t xResult;
        else\r
        {\r
                /* For now pdFAIL will be returned. But prvEMACHandlerTask() is running\r
-               and it will keep on checking the PHY and set ulPHYLinkStatus when necessary. */\r
+               and it will keep on checking the PHY and set 'ulLinkStatusMask' when necessary. */\r
                xResult = pdFAIL;\r
                FreeRTOS_printf( ( "Link Status still low\n" ) ) ;\r
        }\r
@@ -683,6 +615,12 @@ const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
        {\r
        ProtocolPacket_t *pxPacket;\r
 \r
+               #if( ipconfigZERO_COPY_RX_DRIVER != 0 )\r
+               {\r
+                       configASSERT( bReleaseAfterSend != 0 );\r
+               }\r
+               #endif /* ipconfigZERO_COPY_RX_DRIVER */\r
+\r
                /* If the peripheral must calculate the checksum, it wants\r
                the protocol checksum to have a value of zero. */\r
                pxPacket = ( ProtocolPacket_t * ) ( pxDescriptor->pucEthernetBuffer );\r
@@ -697,28 +635,21 @@ const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
        /* Open a do {} while ( 0 ) loop to be able to call break. */\r
        do\r
        {\r
-               if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )\r
+               if( xPhyObject.ulLinkStatusMask != 0 )\r
                {\r
-                       #if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
+                       if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )\r
                        {\r
-                               if( xTXDescriptorSemaphore == NULL )\r
-                               {\r
-                                       break;\r
-                               }\r
-                               if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )\r
-                               {\r
-                                       /* Time-out waiting for a free TX descriptor. */\r
-                                       break;\r
-                               }\r
+                               /* Time-out waiting for a free TX descriptor. */\r
+                               break;\r
                        }\r
-                       #endif /* ipconfigZERO_COPY_TX_DRIVER */\r
 \r
                        /* This function does the actual transmission of the packet. The packet is\r
                        contained in 'pxDescriptor' that is passed to the function. */\r
                        pxDmaTxDesc = xETH.TxDesc;\r
 \r
                        /* Is this buffer available? */\r
-                       if( ( pxDmaTxDesc->Status & ETH_DMATXDESC_OWN ) == 0 )\r
+                       configASSERT ( ( pxDmaTxDesc->Status & ETH_DMATXDESC_OWN ) == 0 );\r
+\r
                        {\r
                                /* Is this buffer available? */\r
                                /* Get bytes in current buffer. */\r
@@ -733,20 +664,20 @@ const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
                                {\r
                                        /* Copy the bytes. */\r
                                        memcpy( ( void * ) pxDmaTxDesc->Buffer1Addr, pxDescriptor->pucEthernetBuffer, ulTransmitSize );\r
-                                       pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL;\r
                                }\r
                                #else\r
                                {\r
                                        /* Move the buffer. */\r
                                        pxDmaTxDesc->Buffer1Addr = ( uint32_t )pxDescriptor->pucEthernetBuffer;\r
-                                       /* Ask to set the IPv4 checksum.\r
-                                       Also need an Interrupt on Completion so that 'vClearTXBuffers()' will be called.. */\r
-                                       pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL | ETH_DMATXDESC_IC;\r
                                        /* The Network Buffer has been passed to DMA, no need to release it. */\r
                                        bReleaseAfterSend = pdFALSE_UNSIGNED;\r
                                }\r
                                #endif /* ipconfigZERO_COPY_TX_DRIVER */\r
 \r
+                               /* Ask to set the IPv4 checksum.\r
+                               Also need an Interrupt on Completion so that 'vClearTXBuffers()' will be called.. */\r
+                               pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL | ETH_DMATXDESC_IC;\r
+\r
                                /* Prepare transmit descriptors to give to DMA. */\r
 \r
                                /* Set LAST and FIRST segment */\r
@@ -758,7 +689,8 @@ const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
 \r
                                /* Point to next descriptor */\r
                                xETH.TxDesc = ( ETH_DMADescTypeDef * ) ( xETH.TxDesc->Buffer2NextDescAddr );\r
-       \r
+                               /* Ensure completion of memory access */\r
+                               __DSB();\r
                                /* Resume DMA transmission*/\r
                                xETH.Instance->DMATPDR = 0;\r
                                iptraceNETWORK_INTERFACE_TRANSMIT();\r
@@ -977,6 +909,8 @@ uint8_t *pucBuffer;
                pxDMARxDescriptor->ControlBufferSize = ETH_DMARXDESC_RCH | (uint32_t)ETH_RX_BUF_SIZE;  \r
                pxDMARxDescriptor->Status = ETH_DMARXDESC_OWN;\r
 \r
+               /* Ensure completion of memory access */\r
+               __DSB();\r
                /* When Rx Buffer unavailable flag is set clear it and resume\r
                reception. */\r
                if( ( xETH.Instance->DMASR & ETH_DMASR_RBUS ) != 0 )\r
@@ -993,305 +927,141 @@ uint8_t *pucBuffer;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vMACBProbePhy( void )\r
-{\r
-uint32_t ulConfig, ulAdvertise, ulLower, ulUpper, ulMACPhyID, ulValue;\r
-TimeOut_t xPhyTime;\r
-TickType_t xRemTime = 0;\r
-#if( EXPECTED_PHY_ID == PHY_ID_DP83848I )\r
-       uint32_t ulPhyControl;\r
-#endif\r
-\r
-       HAL_ETH_ReadPHYRegister(&xETH, PHY_REG_03_PHYSID2, &ulLower);\r
-       HAL_ETH_ReadPHYRegister(&xETH, PHY_REG_02_PHYSID1, &ulUpper);\r
-\r
-       ulMACPhyID = ( ( ulUpper << 16 ) & 0xFFFF0000 ) | ( ulLower & 0xFFF0 );\r
 \r
-       /* The expected ID for the 'LAN8720' is 0x0007c0f0. */\r
-       /* The expected ID for the 'DP83848I' is 0x20005C90. */\r
-\r
-       FreeRTOS_printf( ( "PHY ID %lX (%s)\n", ulMACPhyID,\r
-               ( ulMACPhyID == EXPECTED_PHY_ID ) ? "OK" : "Unknown" ) );\r
+BaseType_t xSTM32_PhyRead( BaseType_t xAddress, BaseType_t xRegister, uint32_t *pulValue )\r
+{\r
+uint16_t usPrevAddress = xETH.Init.PhyAddress;\r
+BaseType_t xResult;\r
+HAL_StatusTypeDef xHALResult;\r
 \r
-       /* Remove compiler warning if FreeRTOS_printf() is not defined. */\r
-       ( void ) ulMACPhyID;\r
+       xETH.Init.PhyAddress = xAddress;\r
+       xHALResult = HAL_ETH_ReadPHYRegister( &xETH, ( uint16_t )xRegister, pulValue );\r
+       xETH.Init.PhyAddress = usPrevAddress;\r
 \r
-    /* Set advertise register. */\r
-       if( ( xPHYProperties.speed == PHY_SPEED_AUTO ) && ( xPHYProperties.duplex == PHY_DUPLEX_AUTO ) )\r
+       if( xHALResult == HAL_OK )\r
        {\r
-               ulAdvertise = ADVERTISE_CSMA | ADVERTISE_ALL;\r
-               /* Reset auto-negotiation capability. */\r
+               xResult = 0;\r
        }\r
        else\r
        {\r
-               ulAdvertise = ADVERTISE_CSMA;\r
-\r
-               if( xPHYProperties.speed == PHY_SPEED_AUTO )\r
-               {\r
-                       if( xPHYProperties.duplex == PHY_DUPLEX_FULL )\r
-                       {\r
-                               ulAdvertise |= ADVERTISE_10FULL | ADVERTISE_100FULL;\r
-                       }\r
-                       else\r
-                       {\r
-                               ulAdvertise |= ADVERTISE_10HALF | ADVERTISE_100HALF;\r
-                       }\r
-               }\r
-               else if( xPHYProperties.duplex == PHY_DUPLEX_AUTO )\r
-               {\r
-                       if( xPHYProperties.speed == PHY_SPEED_10 )\r
-                       {\r
-                               ulAdvertise |= ADVERTISE_10FULL | ADVERTISE_10HALF;\r
-                       }\r
-                       else\r
-                       {\r
-                               ulAdvertise |= ADVERTISE_100FULL | ADVERTISE_100HALF;\r
-                       }\r
-               }\r
-               else if( xPHYProperties.speed == PHY_SPEED_100 )\r
-               {\r
-                       if( xPHYProperties.duplex == PHY_DUPLEX_FULL )\r
-                       {\r
-                               ulAdvertise |= ADVERTISE_100FULL;\r
-                       }\r
-                       else\r
-                       {\r
-                               ulAdvertise |= ADVERTISE_100HALF;\r
-                       }\r
-               }\r
-               else\r
-               {\r
-                       if( xPHYProperties.duplex == PHY_DUPLEX_FULL )\r
-                       {\r
-                               ulAdvertise |= ADVERTISE_10FULL;\r
-                       }\r
-                       else\r
-                       {\r
-                               ulAdvertise |= ADVERTISE_10HALF;\r
-                       }\r
-               }\r
-       }\r
-\r
-       /* Read Control register. */\r
-       HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_00_BMCR, &ulConfig );\r
-\r
-       HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, ulConfig | BMCR_RESET );\r
-       xRemTime = ( TickType_t ) pdMS_TO_TICKS( 1000UL );\r
-       vTaskSetTimeOutState( &xPhyTime );\r
-\r
-       for( ; ; )\r
-       {\r
-               HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_00_BMCR, &ulValue );\r
-               if( ( ulValue & BMCR_RESET ) == 0 )\r
-               {\r
-                       FreeRTOS_printf( ( "BMCR_RESET ready\n" ) );\r
-                       break;\r
-               }\r
-               if( xTaskCheckForTimeOut( &xPhyTime, &xRemTime ) != pdFALSE )\r
-               {\r
-                       FreeRTOS_printf( ( "BMCR_RESET timed out\n" ) );\r
-                       break;\r
-               }\r
+               xResult = -1;\r
        }\r
-       HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, ulConfig & ~BMCR_RESET );\r
+       return xResult;\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
-       vTaskDelay( pdMS_TO_TICKS( 50ul ) );\r
+BaseType_t xSTM32_PhyWrite( BaseType_t xAddress, BaseType_t xRegister, uint32_t ulValue )\r
+{\r
+uint16_t usPrevAddress = xETH.Init.PhyAddress;\r
+BaseType_t xResult;\r
+HAL_StatusTypeDef xHALResult;\r
 \r
-    /* Write advertise register. */\r
-       HAL_ETH_WritePHYRegister( &xETH, PHY_REG_04_ADVERTISE, ulAdvertise );\r
+       xETH.Init.PhyAddress = xAddress;\r
+       xHALResult = HAL_ETH_WritePHYRegister( &xETH, ( uint16_t )xRegister, ulValue );\r
+       xETH.Init.PhyAddress = usPrevAddress;\r
 \r
-       /*\r
-                       AN_EN        AN1         AN0       Forced Mode\r
-                         0           0           0        10BASE-T, Half-Duplex\r
-                         0           0           1        10BASE-T, Full-Duplex\r
-                         0           1           0        100BASE-TX, Half-Duplex\r
-                         0           1           1        100BASE-TX, Full-Duplex\r
-                       AN_EN        AN1         AN0       Advertised Mode\r
-                         1           0           0        10BASE-T, Half/Full-Duplex\r
-                         1           0           1        100BASE-TX, Half/Full-Duplex\r
-                         1           1           0        10BASE-T Half-Duplex\r
-                                                                                          100BASE-TX, Half-Duplex\r
-                         1           1           1        10BASE-T, Half/Full-Duplex\r
-                                                                                          100BASE-TX, Half/Full-Duplex\r
-       */\r
-\r
-    /* Read Control register. */\r
-       HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_00_BMCR, &ulConfig );\r
-\r
-       ulConfig &= ~( BMCR_ANRESTART | BMCR_ANENABLE | BMCR_SPEED100 | BMCR_FULLDPLX );\r
-\r
-       /* HT 12/9/14: always set AN-restart and AN-enable, even though the choices\r
-       are limited. */\r
-       ulConfig |= (BMCR_ANRESTART | BMCR_ANENABLE);\r
-\r
-       if( xPHYProperties.speed == PHY_SPEED_100 )\r
+       if( xHALResult == HAL_OK )\r
        {\r
-               ulConfig |= BMCR_SPEED100;\r
+               xResult = 0;\r
        }\r
-       else if( xPHYProperties.speed == PHY_SPEED_10 )\r
+       else\r
        {\r
-               ulConfig &= ~BMCR_SPEED100;\r
+               xResult = -1;\r
        }\r
+       return xResult;\r
+}\r
+/*-----------------------------------------------------------*/\r
 \r
-       if( xPHYProperties.duplex == PHY_DUPLEX_FULL )\r
-       {\r
-               ulConfig |= BMCR_FULLDPLX;\r
-       }\r
-       else if( xPHYProperties.duplex == PHY_DUPLEX_HALF )\r
-       {\r
-               ulConfig &= ~BMCR_FULLDPLX;\r
-       }\r
+void phy_test()\r
+{\r
+BaseType_t xPhyCount;\r
+BaseType_t xPhyIndex;\r
 \r
-       #if( EXPECTED_PHY_ID == PHY_ID_LAN8720 )\r
-       {\r
-       }\r
-       #elif( EXPECTED_PHY_ID == PHY_ID_DP83848I )\r
+       vPhyInitialise( &xPhyObject, xSTM32_PhyRead, xSTM32_PhyWrite );\r
+       xPhyCount = xPhyDiscover( &xPhyObject );\r
+       FreeRTOS_printf( ( "PHY count %ld\n", xPhyCount ) );\r
+       for( xPhyIndex = 0; xPhyIndex < xPhyCount; xPhyIndex++ )\r
        {\r
-               /* Read PHY Control register. */\r
-               HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_19_PHYCR, &ulPhyControl );\r
+               FreeRTOS_printf( ( "PHY[%d] at address %d ( 0x%08X )\n",\r
+                       xPhyIndex,\r
+                       xPhyObject.ucPhyIndexes[ xPhyIndex ],\r
+                       xPhyObject.ulPhyIDs[ xPhyIndex ] ) );\r
 \r
-               /* Clear bits which might get set: */\r
-               ulPhyControl &= ~( PHYCR_MDIX_EN|PHYCR_MDIX_FORCE );\r
-\r
-               if( xPHYProperties.mdix == PHY_MDIX_AUTO )\r
-               {\r
-                       ulPhyControl |= PHYCR_MDIX_EN;\r
-               }\r
-               else if( xPHYProperties.mdix == PHY_MDIX_CROSSED )\r
-               {\r
-                       /* Force direct link = Use crossed RJ45 cable. */\r
-                       ulPhyControl &= ~PHYCR_MDIX_FORCE;\r
-               }\r
-               else\r
-               {\r
-                       /* Force crossed link = Use direct RJ45 cable. */\r
-                       ulPhyControl |= PHYCR_MDIX_FORCE;\r
-               }\r
-               /* update PHY Control Register. */\r
-               HAL_ETH_WritePHYRegister( &xETH, PHY_REG_19_PHYCR, ulPhyControl );\r
        }\r
-       #endif\r
-       FreeRTOS_printf( ( "+TCP: advertise: %lX config %lX\n", ulAdvertise, ulConfig ) );\r
+       \r
+}\r
 \r
-       /* Now the two values to global values for later use. */\r
-       ulBCRvalue = ulConfig;\r
-       ulACRValue = ulAdvertise;\r
+void vMACBProbePhy( void )\r
+{\r
+       vPhyInitialise( &xPhyObject, xSTM32_PhyRead, xSTM32_PhyWrite );\r
+       xPhyDiscover( &xPhyObject );\r
+       xPhyConfigure( &xPhyObject, &xPHYProperties );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
 static void prvEthernetUpdateConfig( BaseType_t xForce )\r
 {\r
-__IO uint32_t ulTimeout = 0;\r
-uint32_t ulRegValue = 0;\r
-\r
-       FreeRTOS_printf( ( "prvEthernetUpdateConfig: LS %d Force %d\n",\r
-               ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ,\r
-               xForce ) );\r
+       FreeRTOS_printf( ( "prvEthernetUpdateConfig: LS mask %02lX Force %d\n",\r
+               xPhyObject.ulLinkStatusMask,\r
+               ( int )xForce ) );\r
 \r
-       if( ( xForce != pdFALSE ) || ( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) )\r
+       if( ( xForce != pdFALSE ) || ( xPhyObject.ulLinkStatusMask != 0 ) )\r
        {\r
                /* Restart the auto-negotiation. */\r
                if( xETH.Init.AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE )\r
                {\r
-                       /* Enable Auto-Negotiation. */\r
-                       HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, ulBCRvalue | BMCR_ANRESTART );\r
-                       HAL_ETH_WritePHYRegister( &xETH, PHY_REG_04_ADVERTISE, ulACRValue);\r
+                       xPhyStartAutoNegotiation( &xPhyObject, xPhyGetMask( &xPhyObject ) );\r
 \r
-                       /* Wait until the auto-negotiation will be completed */\r
-                       do\r
+                       /* Configure the MAC with the Duplex Mode fixed by the\r
+                       auto-negotiation process. */\r
+                       if( xPhyObject.xPhyProperties.ucDuplex == PHY_DUPLEX_FULL )\r
                        {\r
-                               ulTimeout++;\r
-                               HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_01_BMSR, &ulRegValue );\r
-                       } while( ( ( ulRegValue & PHY_AUTONEGO_COMPLETE) == 0 ) && ( ulTimeout < PHY_READ_TO ) );\r
-\r
-                       HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, ulBCRvalue & ~BMCR_ANRESTART );\r
-\r
-                       if( ulTimeout < PHY_READ_TO )\r
+                               xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;\r
+                       }\r
+                       else\r
                        {\r
-                               /* Reset Timeout counter. */\r
-                               ulTimeout = 0;\r
-\r
-                               HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_01_BMSR, &ulRegValue);\r
-                               if( ( ulRegValue & BMSR_LINK_STATUS ) != 0 )\r
-                               {\r
-                                       ulPHYLinkStatus |= BMSR_LINK_STATUS;\r
-                               }\r
-                               else\r
-                               {\r
-                                       ulPHYLinkStatus &= ~( BMSR_LINK_STATUS );\r
-                               }\r
-\r
-                               #if( EXPECTED_PHY_ID == PHY_ID_LAN8720 )\r
-                               {\r
-                               /* 31 RW PHY Special Control Status */\r
-                               uint32_t ulControlStatus;\r
-\r
-                                       HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_1F_PHYSPCS, &ulControlStatus);\r
-                                       ulRegValue = 0;\r
-                                       if( ( ulControlStatus & PHYSPCS_FULL_DUPLEX ) != 0 )\r
-                                       {\r
-                                               ulRegValue |= PHY_DUPLEX_STATUS;\r
-                                       }\r
-                                       if( ( ulControlStatus & PHYSPCS_SPEED_MASK ) == PHYSPCS_SPEED_10 )\r
-                                       {\r
-                                               ulRegValue |= PHY_SPEED_STATUS;\r
-                                       }\r
-\r
-                               }\r
-                               #elif( EXPECTED_PHY_ID == PHY_ID_DP83848I )\r
-                               {\r
-                                       /* Read the result of the auto-negotiation. */\r
-                                       HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_10_PHY_SR, &ulRegValue);\r
-                               }\r
-                               #endif\r
-                               FreeRTOS_printf( ( ">> Autonego ready: %08lx: %s duplex %u mbit %s status\n",\r
-                                       ulRegValue,\r
-                                       (ulRegValue & PHY_DUPLEX_STATUS) ? "full" : "half",\r
-                                       (ulRegValue & PHY_SPEED_STATUS) ? 10 : 100,\r
-                                       ((ulPHYLinkStatus |= BMSR_LINK_STATUS) != 0) ? "high" : "low" ) );\r
-\r
-                               /* Configure the MAC with the Duplex Mode fixed by the\r
-                               auto-negotiation process. */\r
-                               if( ( ulRegValue & PHY_DUPLEX_STATUS ) != ( uint32_t ) RESET )\r
-                               {\r
-                                       /* Set Ethernet duplex mode to Full-duplex following the\r
-                                       auto-negotiation. */\r
-                                       xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;\r
-                               }\r
-                               else\r
-                               {\r
-                                       /* Set Ethernet duplex mode to Half-duplex following the\r
-                                       auto-negotiation. */\r
-                                       xETH.Init.DuplexMode = ETH_MODE_HALFDUPLEX;\r
-                               }\r
+                               xETH.Init.DuplexMode = ETH_MODE_HALFDUPLEX;\r
+                       }\r
 \r
-                               /* Configure the MAC with the speed fixed by the\r
-                               auto-negotiation process. */\r
-                               if( ( ulRegValue & PHY_SPEED_STATUS) != 0 )\r
-                               {\r
-                                       /* Set Ethernet speed to 10M following the\r
-                                       auto-negotiation. */\r
-                                       xETH.Init.Speed = ETH_SPEED_10M;\r
-                               }\r
-                               else\r
-                               {\r
-                                       /* Set Ethernet speed to 100M following the\r
-                                       auto-negotiation. */\r
-                                       xETH.Init.Speed = ETH_SPEED_100M;\r
-                               }\r
-                       }       /* if( ulTimeout < PHY_READ_TO ) */\r
+                       /* Configure the MAC with the speed fixed by the\r
+                       auto-negotiation process. */\r
+                       if( xPhyObject.xPhyProperties.ucSpeed == PHY_SPEED_10 )\r
+                       {\r
+                               xETH.Init.Speed = ETH_SPEED_10M;\r
+                       }\r
+                       else\r
+                       {\r
+                               xETH.Init.Speed = ETH_SPEED_100M;\r
+                       }\r
                }\r
                else /* AutoNegotiation Disable */\r
                {\r
-               uint16_t usValue;\r
-\r
                        /* Check parameters */\r
                        assert_param( IS_ETH_SPEED( xETH.Init.Speed ) );\r
                        assert_param( IS_ETH_DUPLEX_MODE( xETH.Init.DuplexMode ) );\r
 \r
-                       /* Set MAC Speed and Duplex Mode to PHY */\r
-                       usValue = ( uint16_t ) ( xETH.Init.DuplexMode >> 3 ) | ( uint16_t ) ( xETH.Init.Speed >> 1 );\r
-                       HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, usValue );\r
+                       if( xETH.Init.DuplexMode == ETH_MODE_FULLDUPLEX )\r
+                       {\r
+                               xPhyObject.xPhyPreferences.ucDuplex = PHY_DUPLEX_HALF;\r
+                       }\r
+                       else\r
+                       {\r
+                               xPhyObject.xPhyPreferences.ucDuplex = PHY_DUPLEX_FULL;\r
+                       }\r
+\r
+                       if( xETH.Init.Speed == ETH_SPEED_10M )\r
+                       {\r
+                               xPhyObject.xPhyPreferences.ucSpeed = PHY_SPEED_10;\r
+                       }\r
+                       else\r
+                       {\r
+                               xPhyObject.xPhyPreferences.ucSpeed = PHY_SPEED_100;\r
+                       }\r
+\r
+                       xPhyObject.xPhyPreferences.ucMDI_X = PHY_MDIX_AUTO;\r
+\r
+                       /* Use predefined (fixed) configuration. */\r
+                       xPhyFixedValue( &xPhyObject, xPhyGetMask( &xPhyObject ) );\r
                }\r
 \r
                /* ETHERNET MAC Re-Configuration */\r
@@ -1312,7 +1082,7 @@ BaseType_t xGetPhyLinkStatus( void )
 {\r
 BaseType_t xReturn;\r
 \r
-       if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )\r
+       if( xPhyObject.ulLinkStatusMask != 0 )\r
        {\r
                xReturn = pdPASS;\r
        }\r
@@ -1325,27 +1095,45 @@ BaseType_t xReturn;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+/* Uncomment this in case BufferAllocation_1.c is used. */\r
+\r
+/*\r
+#define niBUFFER_1_PACKET_SIZE         1536\r
+\r
+static __attribute__ ((section(".first_data"))) uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );\r
+\r
+void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )\r
+{\r
+\r
+uint8_t *ucRAMBuffer = ucNetworkPackets;\r
+uint32_t ul;\r
+\r
+       for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )\r
+       {\r
+               pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;\r
+               *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );\r
+               ucRAMBuffer += niBUFFER_1_PACKET_SIZE;\r
+       }\r
+}\r
+*/\r
+/*-----------------------------------------------------------*/\r
+\r
 static void prvEMACHandlerTask( void *pvParameters )\r
 {\r
-TimeOut_t xPhyTime;\r
-TickType_t xPhyRemTime;\r
 UBaseType_t uxLastMinBufferCount = 0;\r
 #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )\r
 UBaseType_t uxLastMinQueueSpace = 0;\r
 #endif\r
 UBaseType_t uxCurrentCount;\r
-BaseType_t xResult = 0;\r
-uint32_t xStatus;\r
+BaseType_t xResult;\r
 const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );\r
 \r
        /* Remove compiler warnings about unused parameters. */\r
        ( void ) pvParameters;\r
 \r
-       vTaskSetTimeOutState( &xPhyTime );\r
-       xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );\r
-\r
        for( ;; )\r
        {\r
+               xResult = 0;\r
                uxCurrentCount = uxGetMinimumFreeNetworkBuffers();\r
                if( uxLastMinBufferCount != uxCurrentCount )\r
                {\r
@@ -1356,7 +1144,6 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
                                uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );\r
                }\r
 \r
-               #if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
                if( xTXDescriptorSemaphore != NULL )\r
                {\r
                static UBaseType_t uxLowestSemCount = ( UBaseType_t ) ETH_TXBUFNB - 1;\r
@@ -1369,7 +1156,7 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
                        }\r
 \r
                }\r
-               #endif\r
+\r
                #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )\r
                {\r
                        uxCurrentCount = uxGetMinimumIPQueueSpace();\r
@@ -1406,12 +1193,8 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
                {\r
                        /* Code to release TX buffers if zero-copy is used. */\r
                        ulISREvents &= ~EMAC_IF_TX_EVENT;\r
-                       #if( ipconfigZERO_COPY_TX_DRIVER != 0 )\r
-                       {\r
-                               /* Check if DMA packets have been delivered. */\r
-                               vClearTXBuffers();\r
-                       }\r
-                       #endif\r
+                       /* Check if DMA packets have been delivered. */\r
+                       vClearTXBuffers();\r
                }\r
 \r
                if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )\r
@@ -1419,34 +1202,10 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
                        /* Future extension: logging about errors that occurred. */\r
                        ulISREvents &= ~EMAC_IF_ERR_EVENT;\r
                }\r
-\r
-               if( xResult > 0 )\r
+               if( xPhyCheckLinkStatus( &xPhyObject, xResult ) != 0 )\r
                {\r
-                       /* A packet was received. No need to check for the PHY status now,\r
-                       but set a timer to check it later on. */\r
-                       vTaskSetTimeOutState( &xPhyTime );\r
-                       xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );\r
-                       xResult = 0;\r
-               }\r
-               else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )\r
-               {\r
-                       HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_01_BMSR, &xStatus );\r
-                       if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )\r
-                       {\r
-                               ulPHYLinkStatus = xStatus;\r
-                               FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );\r
-                               prvEthernetUpdateConfig( pdFALSE );\r
-                       }\r
-\r
-                       vTaskSetTimeOutState( &xPhyTime );\r
-                       if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )\r
-                       {\r
-                               xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );\r
-                       }\r
-                       else\r
-                       {\r
-                               xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );\r
-                       }\r
+                       /* Something has changed to a Link Status, need re-check. */\r
+                       prvEthernetUpdateConfig( pdFALSE );\r
                }\r
        }\r
 }\r
@@ -1456,3 +1215,4 @@ void ETH_IRQHandler( void )
 {\r
        HAL_ETH_IRQHandler( &xETH );\r
 }\r
+\r