]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Common/phyHandling.c
Update TCP/IP tack to latest form Git.
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / portable / NetworkInterface / Common / phyHandling.c
index 9b222c27cd1a27a433ccc6f502abdfbd27e2a58a..bf44d981bde9cc718d1efebf4596c0f7e0b8ab9d 100644 (file)
@@ -1,3 +1,28 @@
+/*\r
+ * FreeRTOS+TCP V2.0.11\r
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
+ * this software and associated documentation files (the "Software"), to deal in\r
+ * the Software without restriction, including without limitation the rights to\r
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
+ * the Software, and to permit persons to whom the Software is furnished to do so,\r
+ * subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ *\r
+ * http://aws.amazon.com/freertos\r
+ * http://www.FreeRTOS.org\r
+ */\r
+\r
 /*\r
  * Handling of Ethernet PHY's\r
  * PHY's communicate with an EMAC either through\r
@@ -24,8 +49,6 @@
 \r
 #include "phyHandling.h"\r
 \r
-#include "eventLogging.h"\r
-\r
 #define phyMIN_PHY_ADDRESS             0\r
 #define phyMAX_PHY_ADDRESS             31\r
 \r
@@ -59,6 +82,7 @@
 /* Bit fields for 'phyREG_00_BMCR', the 'Basic Mode Control Register'. */\r
 #define phyBMCR_FULL_DUPLEX                    0x0100u /* Full duplex. */\r
 #define phyBMCR_AN_RESTART                     0x0200u /* Auto negotiation restart. */\r
+#define phyBMCR_ISOLATE                                0x0400u /* 1 = Isolates 0 = Normal operation. */\r
 #define phyBMCR_AN_ENABLE                      0x1000u /* Enable auto negotiation. */\r
 #define phyBMCR_SPEED_100                      0x2000u /* Select 100Mbps. */\r
 #define phyBMCR_RESET                          0x8000u /* Reset the PHY. */\r
@@ -114,6 +138,8 @@ BaseType_t xResult;
                case PHY_ID_KSZ8051: // same ID as 8041\r
                case PHY_ID_KSZ8081: // same ID as 8041\r
 */\r
+               case PHY_ID_KSZ8081MNXIA:\r
+\r
                case PHY_ID_KSZ8863:\r
                default:\r
                        /* Most PHY's have a 1F_PHYSPCS */\r
@@ -192,7 +218,6 @@ BaseType_t xPhyAddress;
        if( pxPhyObject->xPortCount > 0 )\r
        {\r
                FreeRTOS_printf( ( "PHY ID %lX\n", pxPhyObject->ulPhyIDs[ 0 ] ) );\r
-               eventLogAdd( "PHY ID 0x%lX", pxPhyObject->ulPhyIDs[ 0 ] );\r
        }\r
 \r
        return pxPhyObject->xPortCount;\r
@@ -246,6 +271,8 @@ BaseType_t xPhyIndex;
                        FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );\r
                        break;\r
                }\r
+               /* Block for a while */\r
+               vTaskDelay( pdMS_TO_TICKS( 50ul ) );\r
        }\r
 \r
        /* Clear the reset bits. */\r
@@ -258,7 +285,7 @@ BaseType_t xPhyIndex;
        }\r
 \r
        vTaskDelay( pdMS_TO_TICKS( 50ul ) );\r
-       eventLogAdd( "PHY reset %d ports", (int)pxPhyObject->xPortCount );\r
+\r
        return ulDoneMask;\r
 }\r
 /*-----------------------------------------------------------*/\r
@@ -367,7 +394,7 @@ BaseType_t xPhyIndex;
 \r
                ulConfig |= phyBMCR_AN_ENABLE;\r
 \r
-               if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_100 )\r
+               if( ( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_100 ) || ( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_AUTO ) )\r
                {\r
                        ulConfig |= phyBMCR_SPEED_100;\r
                }\r
@@ -376,7 +403,7 @@ BaseType_t xPhyIndex;
                        ulConfig &= ~phyBMCR_SPEED_100;\r
                }\r
 \r
-               if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL )\r
+               if( ( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL ) || ( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_AUTO ) )\r
                {\r
                        ulConfig |= phyBMCR_FULL_DUPLEX;\r
                }\r
@@ -413,11 +440,10 @@ BaseType_t xPhyIndex;
                }\r
 \r
                FreeRTOS_printf( ( "+TCP: advertise: %04lX config %04lX\n", ulAdvertise, ulConfig ) );\r
-               eventLogAdd( "adv: %04lX config %04lX", ulAdvertise, ulConfig );\r
        }\r
 \r
        /* Keep these values for later use. */\r
-       pxPhyObject->ulBCRValue = ulConfig;\r
+       pxPhyObject->ulBCRValue = ulConfig & ~phyBMCR_ISOLATE;\r
        pxPhyObject->ulACRValue = ulAdvertise;\r
 \r
        return 0;\r
@@ -476,7 +502,6 @@ TimeOut_t xTimer;
                        pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, pxPhyObject->ulBCRValue | phyBMCR_AN_RESTART );\r
                }\r
        }\r
-eventLogAdd( "AN start" );\r
        xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( 3000UL );\r
        vTaskSetTimeOutState( &xTimer );\r
        ulDoneMask = 0;\r
@@ -507,11 +532,10 @@ eventLogAdd( "AN start" );
                if( xTaskCheckForTimeOut( &xTimer, &xRemainingTime ) != pdFALSE )\r
                {\r
                        FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );\r
-                       eventLogAdd( "ANtimed out");\r
                        break;\r
                }\r
+               vTaskDelay( pdMS_TO_TICKS( 50 ) );\r
        }\r
-eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );\r
 \r
        if( ulDoneMask != ( uint32_t)0u )\r
        {\r
@@ -541,7 +565,43 @@ eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );
                                ulPHYLinkStatus &= ~( phyBMSR_LINK_STATUS );\r
                        }\r
 \r
-                       if( xHas_1F_PHYSPCS( ulPhyID ) )\r
+                       if( ulPhyID == PHY_ID_KSZ8081MNXIA )\r
+                       {\r
+                       uint32_t ulControlStatus;\r
+\r
+                               pxPhyObject->fnPhyRead( xPhyAddress, 0x1E, &ulControlStatus);\r
+                               switch( ulControlStatus & 0x07 )\r
+                               {\r
+                               case 0x01:\r
+                               case 0x05:\r
+//     [001] = 10BASE-T half-duplex\r
+//     [101] = 10BASE-T full-duplex\r
+                                       /* 10 Mbps. */\r
+                                       ulRegValue |= phyPHYSTS_SPEED_STATUS;\r
+                                       break;\r
+                               case 0x02:\r
+                               case 0x06:\r
+//     [010] = 100BASE-TX half-duplex\r
+//     [110] = 100BASE-TX full-duplex\r
+                                       break;\r
+                               }\r
+                               switch( ulControlStatus & 0x07 )\r
+                               {\r
+                               case 0x05:\r
+                               case 0x06:\r
+//     [101] = 10BASE-T full-duplex\r
+//     [110] = 100BASE-TX full-duplex\r
+                                       /* Full duplex. */\r
+                                       ulRegValue |= phyPHYSTS_DUPLEX_STATUS;\r
+                                       break;\r
+                               case 0x01:\r
+                               case 0x02:\r
+//     [001] = 10BASE-T half-duplex\r
+//     [010] = 100BASE-TX half-duplex\r
+                                       break;\r
+                               }\r
+                       }\r
+                       else if( xHas_1F_PHYSPCS( ulPhyID ) )\r
                        {\r
                        /* 31 RW PHY Special Control Status */\r
                        uint32_t ulControlStatus;\r
@@ -556,7 +616,6 @@ eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );
                                {\r
                                        ulRegValue |= phyPHYSTS_SPEED_STATUS;\r
                                }\r
-\r
                        }\r
                        else\r
                        {\r
@@ -569,25 +628,6 @@ eventLogAdd( "AN done %02lX / %02lX", ulDoneMask, ulPhyMask );
                                ( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) ? "full" : "half",\r
                                ( ulRegValue & phyPHYSTS_SPEED_STATUS ) ? 10 : 100,\r
                                ( ( ulPHYLinkStatus |= phyBMSR_LINK_STATUS ) != 0) ? "high" : "low" ) );\r
-                       eventLogAdd( "%s duplex %u mbit %s st",\r
-                               ( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) ? "full" : "half",\r
-                               ( ulRegValue & phyPHYSTS_SPEED_STATUS ) ? 10 : 100,\r
-                               ( ( ulPHYLinkStatus |= phyBMSR_LINK_STATUS ) != 0) ? "high" : "low" );\r
-{\r
-       uint32_t regs[4];\r
-       int i,j;\r
-       int address = 0x10;\r
-       for (i = 0; i < 4; i++)\r
-       {\r
-               for (j = 0; j < 4; j++)\r
-               {\r
-                       pxPhyObject->fnPhyRead( xPhyAddress, address, regs + j );\r
-                       address++;\r
-               }\r
-               eventLogAdd("%04lX %04lX %04lX %04lX",\r
-                       regs[0], regs[1], regs[2], regs[3]);\r
-       }\r
-}\r
                        if( ( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) != ( uint32_t )0u )\r
                        {\r
                                pxPhyObject->xPhyProperties.ucDuplex = PHY_DUPLEX_FULL;\r
@@ -624,6 +664,15 @@ BaseType_t xNeedCheck = pdFALSE;
                but set a timer to check it later on. */\r
                vTaskSetTimeOutState( &( pxPhyObject->xLinkStatusTimer ) );\r
                pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_HIGH_CHECK_TIME_MS );\r
+               for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )\r
+               {\r
+                       if( ( pxPhyObject->ulLinkStatusMask & ulBitMask ) == 0ul )\r
+                       {\r
+                               pxPhyObject->ulLinkStatusMask |= ulBitMask;\r
+                               FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", pxPhyObject->ulLinkStatusMask ) );\r
+                               xNeedCheck = pdTRUE;\r
+                       }\r
+               }\r
        }\r
        else if( xTaskCheckForTimeOut( &( pxPhyObject->xLinkStatusTimer ), &( pxPhyObject->xLinkStatusRemaining ) ) != pdFALSE )\r
        {\r
@@ -644,7 +693,6 @@ BaseType_t xNeedCheck = pdFALSE;
                                                pxPhyObject->ulLinkStatusMask &= ~( ulBitMask );\r
                                        }\r
                                        FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", pxPhyObject->ulLinkStatusMask ) );\r
-                                       eventLogAdd( "PHY LS now %02lX", pxPhyObject->ulLinkStatusMask );\r
                                        xNeedCheck = pdTRUE;\r
                                }\r
                        }\r