]> git.sur5r.net Git - freertos/blobdiff - Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/mss_ethernet_mac/mss_ethernet_mac.c
Update MAC drivers so they use a uIP specific zero copy mechanism.
[freertos] / Demo / CORTEX_A2F200_IAR_and_Keil / MicroSemi_Code / drivers / mss_ethernet_mac / mss_ethernet_mac.c
index 5ebea2eb6d29de1f14d9340056209e6cb37c515f..a138492498785078779473f6effe9a89b857d98d 100644 (file)
@@ -9,9 +9,14 @@
  *\r
  ******************************************************************************/\r
 \r
+/*\r
+ * NOTE:  This driver has been roughly modified specifically for use with the\r
+ * uIP stack.  It is no longer a generic driver.\r
+ */\r
+\r
 #ifdef __cplusplus\r
 extern "C" {\r
-#endif \r
+#endif\r
 \r
 #include "FreeRTOS.h"\r
 #include "task.h"\r
@@ -54,11 +59,11 @@ extern "C" {
 /* Allocating this many buffers will always ensure there is one free as, even\r
 though TX_RING_SIZE is set to two, the two Tx descriptors will only ever point\r
 to the same buffer. */\r
-#define macNUM_BUFFERS RX_RING_SIZE + TX_RING_SIZE + 1\r
+#define macNUM_BUFFERS RX_RING_SIZE + TX_RING_SIZE + 2\r
 #define macBUFFER_SIZE 1488\r
 \r
 /***************************************************************/\r
-MAC_instance_t g_mss_mac __attribute__((aligned(4)));\r
+MAC_instance_t g_mss_mac;\r
 \r
 /**************************** INTERNAL DATA ***********************************/\r
 #define ERROR_MESSAGE_COUNT            8\r
@@ -78,15 +83,16 @@ static const int8_t ErrorMessages[][MAX_ERROR_MESSAGE_WIDTH] = {
 /*\r
  * Null variables\r
  */\r
-static MAC_instance_t*         NULL_instance;\r
 static uint8_t*                NULL_buffer;\r
 static MSS_MAC_callback_t      NULL_callback;\r
+\r
+/* Declare the uip_buf as a pointer, rather than the traditional array, as this\r
+is a zero copy driver.  uip_buf just gets set to whichever buffer is being\r
+processed. */\r
 unsigned char *uip_buf = NULL;\r
 \r
 /**************************** INTERNAL FUNCTIONS ******************************/\r
 \r
-static int32_t MAC_test_instance( void );\r
-\r
 static int32_t MAC_dismiss_bad_frames( void );\r
 static int32_t MAC_send_setup_frame( void );\r
 \r
@@ -109,11 +115,16 @@ static void MAC_release_buffer( unsigned char *pcBufferToRelease );
        #error This uIP Ethernet driver required TX_RING_SIZE to be set to 2\r
 #endif\r
 \r
-/* Buffers that will dynamically be allocated to/from the Tx and Rx descriptors. */\r
-static unsigned char ucMACBuffers[ macNUM_BUFFERS ][ macBUFFER_SIZE ] __attribute__((aligned(4)));\r
+/* Buffers that will dynamically be allocated to/from the Tx and Rx descriptors.\r
+The union is used for alignment only. */\r
+static union xMAC_BUFFERS\r
+{\r
+       unsigned long ulAlignmentVariable; /* For alignment only, not used anywhere. */\r
+       unsigned char ucBuffer[ macNUM_BUFFERS ][ macBUFFER_SIZE ];\r
+} xMACBuffers;\r
 \r
-/* Each array position indicated whether or not the buffer of the same index\r
-is currently allocated to a descriptor (pdFALSE) or is free for use (pdTRUE). */\r
+/* Each array position indicates whether or not the buffer of the same index\r
+is currently allocated to a descriptor (pdTRUE) or is free for use (pdFALSE). */\r
 static unsigned char ucMACBufferInUse[ macNUM_BUFFERS ] = { 0 };\r
 \r
 /***************************************************************************//**\r
@@ -169,7 +180,7 @@ MSS_MAC_init
                \r
                /* Allocate a buffer to the descriptor, then mark the buffer as in use\r
                (not free). */\r
-        g_mss_mac.rx_descriptors[a].buffer_1 = ( unsigned long ) &( ucMACBuffers[ a ][ 0 ] );\r
+        g_mss_mac.rx_descriptors[a].buffer_1 = ( unsigned long ) &( xMACBuffers.ucBuffer[ a ][ 0 ] );\r
                ucMACBufferInUse[ a ] = pdTRUE;\r
     }\r
     g_mss_mac.rx_descriptors[RX_RING_SIZE-1].descriptor_1 |= RDES1_RER;\r
@@ -189,8 +200,6 @@ MSS_MAC_init
     MAC_BITBAND->CSR0_BAR = (uint32_t)BUS_ARBITRATION_SCHEME;\r
 \r
     /* Fixed settings */\r
-    /* No automatic polling */\r
-    MAC->CSR0 = MAC->CSR0 &~ CSR0_TAP_MASK;\r
     /* No space between descriptors */\r
     MAC->CSR0 = MAC->CSR0 &~ CSR0_DSL_MASK;\r
     /* General-purpose timer works in continuous mode */\r
@@ -198,19 +207,25 @@ MSS_MAC_init
     /* Start general-purpose */\r
     MAC->CSR11 =  (MAC->CSR11 & ~CSR11_TIM_MASK) | (0x0000FFFFuL << CSR11_TIM_SHIFT);\r
 \r
-    /* Disable promiscuous mode */\r
-    MAC_BITBAND->CSR6_PR = 0u;\r
-\r
-    /* Enable store and forward */\r
-    MAC_BITBAND->CSR6_SF = 1u;\r
+       /* Disable transmit interrupt mitigation. */\r
+       MAC->CSR11 = ( MAC->CSR11 & ~CSR11_TT_MASK );\r
+       MAC->CSR11 = ( MAC->CSR11 & ~CSR11_NTP_MASK );\r
 \r
+       /* Automatic Tx descriptor polling. */\r
+       MAC->CSR0 = ( MAC->CSR0 & ~CSR0_TAP_MASK );\r
+       MAC->CSR0 = ( MAC->CSR0 | ( 0x01 << CSR0_TAP_SHIFT ) );\r
+       \r
     /* Set descriptors */\r
     MAC->CSR3 = (uint32_t)&(g_mss_mac.rx_descriptors[0].descriptor_0);\r
     MAC->CSR4 = (uint32_t)&(g_mss_mac.tx_descriptors[0].descriptor_0);\r
-    \r
+\r
        /* enable normal interrupts */\r
     MAC_BITBAND->CSR7_NIE = 1u;\r
 \r
+    /* Set default MAC address and reset mac filters */\r
+       MAC_memcpy( g_mss_mac.mac_address, mac_address, 6u );\r
+       MSS_MAC_set_mac_address((uint8_t *)mac_address);\r
+       \r
     /* Detect PHY */\r
     if( g_mss_mac.phy_address > MSS_PHY_ADDRESS_MAX )\r
     {\r
@@ -221,21 +236,11 @@ MSS_MAC_init
     /* Reset PHY */\r
     PHY_reset();\r
 \r
-       /* Set flags */\r
-    g_mss_mac.flags = FLAG_MAC_INIT_DONE | FLAG_PERFECT_FILTERING;\r
-\r
        /* Configure chip according to PHY status */\r
     MSS_MAC_auto_setup_link();\r
-\r
-    /* Set default MAC address and reset mac filters */\r
-       MAC_memcpy( g_mss_mac.mac_address, mac_address, 6u );\r
-       MSS_MAC_set_mac_filters( 0u, NULL_buffer );\r
-       MAC_BITBAND->CSR6_RA = 1; /* Receive all. */\r
-       MAC_BITBAND->CSR6_PR = 1; /* Promiscuous mode. */\r
-       MSS_MAC_set_mac_address((uint8_t *)mac_address);\r
        \r
        /* Ensure uip_buf starts by pointing somewhere. */\r
-       uip_buf = MAC_obtain_buffer();\r
+       uip_buf = MAC_obtain_buffer();  \r
 }\r
 \r
 \r
@@ -264,8 +269,6 @@ MSS_MAC_configure
 {\r
     int32_t ret;\r
 \r
-    configASSERT( MAC_test_instance() == MAC_OK );\r
-\r
     ret = MAC_stop_transmission();\r
     configASSERT( ret == MAC_OK );\r
 \r
@@ -275,7 +278,7 @@ MSS_MAC_configure
     MAC_BITBAND->CSR6_RA = (uint32_t)(((configuration & MSS_MAC_CFG_RECEIVE_ALL) != 0u) ? 1u : 0u );\r
     MAC_BITBAND->CSR6_TTM = (((configuration & MSS_MAC_CFG_TRANSMIT_THRESHOLD_MODE) != 0u) ? 1u : 0u );\r
     MAC_BITBAND->CSR6_SF = (uint32_t)(((configuration & MSS_MAC_CFG_STORE_AND_FORWARD) != 0u) ? 1u : 0u );\r
-    \r
+\r
     switch( configuration & MSS_MAC_CFG_THRESHOLD_CONTROL_11 ) {\r
     case MSS_MAC_CFG_THRESHOLD_CONTROL_00:\r
         MAC->CSR6 = MAC->CSR6 & ~CSR6_TR_MASK;\r
@@ -327,8 +330,6 @@ MSS_MAC_get_configuration( void )
 {\r
     uint32_t configuration;\r
 \r
-    configASSERT( MAC_test_instance() == MAC_OK );\r
-\r
     configuration = 0u;\r
     if( MAC_BITBAND->CSR6_RA != 0u ) {\r
         configuration |= MSS_MAC_CFG_RECEIVE_ALL;\r
@@ -375,7 +376,7 @@ MSS_MAC_get_configuration( void )
     if( MAC_BITBAND->CSR6_HP != 0u ) {\r
         configuration |= MSS_MAC_CFG_HASH_PERFECT_RECEIVE_FILTERING_MODE;\r
     }\r
-    \r
+\r
     return (int32_t)configuration;\r
 }\r
 \r
@@ -387,11 +388,11 @@ MSS_MAC_get_configuration( void )
   the transmit FIFO and then activates the transmitter for this packet. If space\r
   is available in the FIFO, the function will return once pac_len bytes of the\r
   packet have been placed into the FIFO and the transmitter has been started.\r
-  This function will not wait for the transmission to complete. \r
+  This function will not wait for the transmission to complete.\r
 \r
   @return\r
     The function returns zero if a timeout occurs otherwise it returns size of the packet.\r
-    \r
+\r
   @see   MAC_rx_packet()\r
  */\r
 \r
@@ -404,9 +405,6 @@ MSS_MAC_tx_packet
        uint32_t desc;\r
        unsigned long ulDescriptor;\r
     int32_t error = MAC_OK;\r
-       extern unsigned char *uip_buf;\r
-\r
-    configASSERT( MAC_test_instance() == MAC_OK );\r
 \r
     configASSERT( uip_buf != NULL_buffer );\r
 \r
@@ -419,28 +417,34 @@ MSS_MAC_tx_packet
 \r
        /* Check if second descriptor is free, if it is then the first must\r
        also be free. */\r
-       if(((g_mss_mac.tx_descriptors[ 1 ].descriptor_0) & TDES0_OWN) == TDES0_OWN )\r
+       if( ( ( (g_mss_mac.tx_descriptors[ 0 ].descriptor_0) & TDES0_OWN) == TDES0_OWN ) || ( ( (g_mss_mac.tx_descriptors[ 1 ].descriptor_0) & TDES0_OWN) == TDES0_OWN ) )\r
        {\r
                error = MAC_BUFFER_IS_FULL;\r
+               \r
+               /* Check the buffers pointed to by the Tx descriptors, just in case a Tx\r
+               interrupt has been missed and a free buffer remains marked as in use. */\r
+               MSS_MAC_CheckTxBufferStatus();\r
        }\r
 \r
+       \r
        if( error == MAC_OK )\r
        {\r
-               /* Assumed TX_RING_SIZE == 2. */\r
+               /* Assumed TX_RING_SIZE == 2.  A #error directive checks this is the\r
+               case. */\r
                for( ulDescriptor = 0; ulDescriptor < TX_RING_SIZE; ulDescriptor++ )\r
                {\r
-                       g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 = 0u;\r
+                       g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 = 0u;\r
 \r
                        if( (g_mss_mac.flags & FLAG_CRC_DISABLE) != 0u ) {\r
-                               g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 |= TDES1_AC;\r
+                               g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= TDES1_AC;\r
                        }\r
 \r
                        /* Every buffer can hold a full frame so they are always first and last\r
                           descriptor */\r
-                       g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 |= TDES1_LS | TDES1_FS | TDES1_IC;\r
+               g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= TDES1_LS | TDES1_FS | TDES1_IC;\r
 \r
                        /* set data size */\r
-                       g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_1 |= usLength;\r
+                       g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_1 |= usLength;\r
 \r
                        /* reset end of ring */\r
                        g_mss_mac.tx_descriptors[TX_RING_SIZE-1].descriptor_1 |= TDES1_TER;\r
@@ -451,10 +455,10 @@ MSS_MAC_tx_packet
                        }\r
 \r
                        /* The data buffer is assigned to the Tx descriptor. */\r
-                       g_mss_mac.tx_descriptors[ ulDescriptor ].buffer_1 = ( unsigned long ) uip_buf;\r
+                       g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].buffer_1 = ( unsigned long ) uip_buf;\r
 \r
                        /* update counters */\r
-                       desc = g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_0;\r
+                       desc = g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0;\r
                        if( (desc & TDES0_LO) != 0u ) {\r
                                g_mss_mac.statistics.tx_loss_of_carrier++;\r
                        }\r
@@ -474,25 +478,22 @@ MSS_MAC_tx_packet
                                (desc >> TDES0_CC_OFFSET) & TDES0_CC_MASK;\r
 \r
                        /* Give ownership of descriptor to the MAC */\r
-                       g_mss_mac.tx_descriptors[ ulDescriptor ].descriptor_0 = RDES0_OWN;\r
-               }\r
-\r
-               /* Start transmission */\r
-               MAC_start_transmission();\r
-               g_mss_mac.tx_desc_index = 0;\r
-               /* transmit poll demand */\r
-               MAC->CSR1 = 1u;\r
+                       g_mss_mac.tx_descriptors[ g_mss_mac.tx_desc_index ].descriptor_0 = RDES0_OWN;\r
+                       \r
+                       g_mss_mac.tx_desc_index = (g_mss_mac.tx_desc_index + 1u) % (uint32_t)TX_RING_SIZE;\r
+                       \r
+                       MAC_start_transmission();\r
+                       MAC->CSR1 = 1u;\r
+               }               \r
     }\r
-\r
-\r
-       \r
        \r
     if (error == MAC_OK)\r
     {\r
-               /* The buffer uip_buf was pointing to is now under the control of the \r
-               MAC (it is being transmitted).  Set uip_buf to point to a free buffer. */\r
-               uip_buf = MAC_obtain_buffer();\r
         error = (int32_t)usLength;\r
+               \r
+               /* The buffer pointed to by uip_buf is now assigned to a Tx descriptor.\r
+               Find anothere free buffer for uip_buf. */\r
+               uip_buf = MAC_obtain_buffer();\r
     }\r
     else\r
     {\r
@@ -517,8 +518,6 @@ MSS_MAC_rx_pckt_size
 )\r
 {\r
     int32_t retval;\r
-    configASSERT( MAC_test_instance() == MAC_OK );\r
-\r
     MAC_dismiss_bad_frames();\r
 \r
     if( (g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 &    RDES0_OWN) != 0u )\r
@@ -540,7 +539,7 @@ MSS_MAC_rx_pckt_size
  * Receives a packet from the Ethernet Controller into the uIP stack.\r
  * This function reads a packet from the receive FIFO of the controller and\r
  * places it into uip_buf.\r
\r
+\r
  * @return              Size of packet if packet fits in uip_buf.\r
  *                                         0 if there is no received packet.\r
  * @see   MAC_rx_pckt_size()\r
@@ -554,8 +553,6 @@ MSS_MAC_rx_packet
 {\r
        uint16_t frame_length=0u;\r
 \r
-    configASSERT( MAC_test_instance() == MAC_OK );\r
-    \r
     MAC_dismiss_bad_frames();\r
 \r
     if( (g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].descriptor_0 & RDES0_OWN) == 0u )\r
@@ -570,7 +567,7 @@ MSS_MAC_rx_packet
         if( frame_length > macBUFFER_SIZE ) {\r
                return MAC_NOT_ENOUGH_SPACE;\r
         }\r
-       \r
+\r
                /* uip_buf is about to point to the buffer that contains the received\r
                data, mark the buffer that uip_buf is currently pointing to as free\r
                again. */\r
@@ -590,7 +587,7 @@ MSS_MAC_rx_packet
 /***************************************************************************//**\r
  * Receives a packet from the Ethernet Controller.\r
  * This function reads a packet from the receive FIFO of the controller and\r
- * sets the address of pacData to the received data. \r
+ * sets the address of pacData to the received data.\r
  * If time_out parameter is zero the function will return\r
  * immediately (after the copy operation if data is available. Otherwise the function\r
  * will keep trying to read till time_out expires or data is read, if MSS_MAC_BLOCKING\r
@@ -619,8 +616,6 @@ MSS_MAC_rx_packet_ptrset
        uint16_t frame_length = 0u;\r
     int8_t exit = 0;\r
 \r
-    configASSERT( MAC_test_instance() == MAC_OK );\r
-\r
     configASSERT(  (time_out == MSS_MAC_BLOCKING) ||\r
                        (time_out == MSS_MAC_NONBLOCKING) ||\r
                        ((time_out >= 1) && (time_out <= 0x01000000UL)) );\r
@@ -658,11 +653,11 @@ MSS_MAC_rx_packet_ptrset
 \r
        /* Here we are setting the buffer 'pacData' address to the address\r
           RX descriptor address. After this is called, the following function\r
-          must be called 'MAC_prepare_rx_descriptor' \r
+          must be called 'MAC_prepare_rx_descriptor'\r
           to prepare the current rx descriptor for receiving the next packet.\r
-       */       \r
-       *pacData = (uint8_t *)g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].buffer_1 ;         \r
-        \r
+       */\r
+       *pacData = (uint8_t *)g_mss_mac.rx_descriptors[ g_mss_mac.rx_desc_index ].buffer_1 ;\r
+\r
     }\r
     return ((int32_t)frame_length);\r
 }\r
@@ -684,8 +679,6 @@ MSS_MAC_link_status
 {\r
        uint32_t link;\r
 \r
-    configASSERT( MAC_test_instance() == MAC_OK );\r
-\r
     link = PHY_link_status();\r
     if( link == MSS_MAC_LINK_STATUS_LINK ) {\r
        link |= PHY_link_type();\r
@@ -711,7 +704,6 @@ MSS_MAC_auto_setup_link
 )\r
 {\r
        int32_t link;\r
-    configASSERT( MAC_test_instance() == MAC_OK );\r
 \r
     PHY_auto_negotiate();\r
 \r
@@ -746,7 +738,6 @@ MSS_MAC_set_mac_address
     const uint8_t *new_address\r
 )\r
 {\r
-    configASSERT( MAC_test_instance() == MAC_OK );\r
     /* Check if the new address is unicast */\r
     configASSERT( (new_address[0]&1) == 0 );\r
 \r
@@ -782,8 +773,6 @@ MSS_MAC_get_mac_address
     uint8_t *address\r
 )\r
 {\r
-    configASSERT( MAC_test_instance() == MAC_OK );\r
-\r
        MAC_memcpy( address, g_mss_mac.mac_address, 6u );\r
 }\r
 \r
@@ -801,7 +790,6 @@ MSS_MAC_set_mac_filters
        const uint8_t *filters\r
 )\r
 {\r
-    configASSERT( MAC_test_instance() == MAC_OK );\r
     configASSERT( (filter_count==0) || (filters != NULL_buffer) );\r
     /* Check if the mac addresses is multicast */\r
     {\r
@@ -857,8 +845,6 @@ void EthernetMAC_IRQHandler( void )
     uint32_t events;\r
     uint32_t intr_status;\r
 \r
-    configASSERT( MAC_test_instance() == MAC_OK );\r
-\r
     events = 0u;\r
     intr_status = MAC->CSR5;\r
 \r
@@ -876,7 +862,7 @@ void EthernetMAC_IRQHandler( void )
 \r
     /* Clear interrupts */\r
     MAC->CSR5 = CSR5_INT_BITS;\r
-    \r
+\r
     if( (events != 0u) && (g_mss_mac.listener != NULL_callback) ) {\r
         g_mss_mac.listener( events );\r
     }\r
@@ -901,12 +887,10 @@ MSS_MAC_set_callback
     MSS_MAC_callback_t listener\r
 )\r
 {\r
-    configASSERT( MAC_test_instance() == MAC_OK );\r
-\r
        /* disable tx and rx interrupts */\r
     MAC_BITBAND->CSR7_RIE = 0u;\r
     MAC_BITBAND->CSR7_TIE = 0u;\r
-    \r
+\r
     g_mss_mac.listener = listener;\r
 \r
        if( listener != NULL_callback ) {\r
@@ -934,8 +918,6 @@ MSS_MAC_last_error
 {\r
        int8_t error_msg_nb;\r
     const int8_t* returnvalue;\r
-    \r
-    configASSERT( MAC_test_instance() == MAC_OK );\r
 \r
        error_msg_nb = -(g_mss_mac.last_error);\r
        if( error_msg_nb >= ERROR_MESSAGE_COUNT ) {\r
@@ -962,7 +944,6 @@ MSS_MAC_get_statistics
 )\r
 {\r
     uint32_t returnval = 0u;\r
-    configASSERT( MAC_test_instance() == MAC_OK );\r
 \r
        switch( stat_id ) {\r
        case MSS_MAC_RX_INTERRUPTS:\r
@@ -1029,31 +1010,6 @@ MSS_MAC_get_statistics
 \r
 /**************************** INTERNAL FUNCTIONS ******************************/\r
 \r
-/***************************************************************************//**\r
- * Checks if instace is valid.\r
- */\r
-static int32_t\r
-MAC_test_instance\r
-(\r
-    void\r
-)\r
-{\r
-    uint32_t val1;\r
-    uint32_t val2;\r
-    int32_t retval = MAC_WRONG_PARAMETER;\r
-\r
-    val1 = MAC->CSR3;\r
-    val2 = MAC->CSR4;\r
-\r
-    if( (&g_mss_mac != NULL_instance) &&\r
-       ((g_mss_mac.flags & FLAG_MAC_INIT_DONE) != 0u) &&\r
-       ( val1 == (uint32_t)g_mss_mac.rx_descriptors) &&\r
-       (val2 == (uint32_t)g_mss_mac.tx_descriptors ) )\r
-    {\r
-       retval = MAC_OK;\r
-    }\r
-    return retval;\r
-}\r
 \r
 /***************************************************************************//**\r
  * Prepares current rx descriptor for receiving.\r
@@ -1092,7 +1048,7 @@ MSS_MAC_prepare_rx_descriptor
        if( (desc & RDES0_CE) != 0u ) {\r
                g_mss_mac.statistics.rx_crc_error++;\r
        }\r
-    \r
+\r
        desc = MAC->CSR8;\r
        g_mss_mac.statistics.rx_fifo_overflow +=\r
                (desc & (CSR8_OCO_MASK|CSR8_FOC_MASK)) >> CSR8_FOC_SHIFT;\r
@@ -1178,15 +1134,15 @@ MAC_send_setup_frame
 \r
     /* Set descriptor */\r
     MAC->CSR4 = (uint32_t)&descriptor;\r
-    \r
+\r
        /* Start transmission */\r
     MAC_start_transmission();\r
 \r
     /* Wait until transmission over */\r
     ret = MAC_OK;\r
     MAC_set_time_out( (uint32_t)SETUP_FRAME_TIME_OUT );\r
-    \r
-    while( (((MAC->CSR5 & CSR5_TS_MASK) >> CSR5_TS_SHIFT) != \r
+\r
+    while( (((MAC->CSR5 & CSR5_TS_MASK) >> CSR5_TS_SHIFT) !=\r
        CSR5_TS_SUSPENDED) && (MAC_OK == ret) )\r
     {\r
        /* transmit poll demand */\r
@@ -1200,7 +1156,7 @@ MAC_send_setup_frame
 \r
     /* Set tx descriptor */\r
     MAC->CSR4 = (uint32_t)g_mss_mac.tx_descriptors;\r
-    \r
+\r
     /* Start receiving and transmission */\r
     MAC_start_receiving();\r
     MAC_start_transmission();\r
@@ -1224,7 +1180,7 @@ MAC_stop_transmission
 {\r
     int32_t retval = MAC_OK;\r
     MAC_set_time_out( (uint16_t)STATE_CHANGE_TIME_OUT );\r
-    \r
+\r
        while( (((MAC->CSR5 & CSR5_TS_MASK) >> CSR5_TS_SHIFT) !=\r
                CSR5_TS_STOPPED) && (retval == MAC_OK) )\r
        {\r
@@ -1305,7 +1261,7 @@ MAC_dismiss_bad_frames
 {\r
        int32_t dc = 0;\r
        int8_t cont = 1;\r
-    \r
+\r
        if( MAC_BITBAND->CSR6_PB != 0u ) {\r
                /* User wants bad frames too, don't dismiss anything */\r
                cont = 0;\r
@@ -1362,14 +1318,14 @@ MAC_get_time_out
 {\r
        uint32_t timer;\r
        uint32_t time = 0u;\r
-    \r
+\r
        timer = ( MAC->CSR11 & CSR11_TIM_MASK );\r
-    \r
+\r
        if( timer > g_mss_mac.last_timer_value ) {\r
                time = 0x0000ffffUL;\r
        }\r
        time += g_mss_mac.last_timer_value - timer;\r
-    \r
+\r
        if( MAC_BITBAND->CSR6_TTM == 0u ) {\r
                time *= 10u;\r
        }\r
@@ -1414,10 +1370,6 @@ static void MAC_memset_All(MAC_instance_t *s, uint32_t c)
        MAC_memset( s->mac_address, (uint8_t)c, 6u );\r
        MAC_memset( s->mac_filter_data, (uint8_t)c, 90u );\r
     s->phy_address = (uint8_t)c;\r
-//    for(count = 0; count<RX_RING_SIZE ;count++)\r
-//    {\r
-//        MAC_memset(s->rx_buffers[count], (uint8_t)c, (MSS_RX_BUFF_SIZE + 4u) );\r
-//    }\r
     s->rx_desc_index =c;\r
     for(count = 0; count<RX_RING_SIZE ;count++)\r
     {\r
@@ -1445,10 +1397,6 @@ static void MAC_memset_All(MAC_instance_t *s, uint32_t c)
     s->statistics.tx_no_carrier = c;\r
     s->statistics.tx_underflow_error = c;\r
     s->time_out_value = c;\r
-//    for(count = 0; count < TX_RING_SIZE ;count++)\r
-//    {\r
-//        MAC_memset( s->tx_buffers[count], (uint8_t)c, MSS_TX_BUFF_SIZE );\r
-//    }\r
     s->tx_desc_index = c;\r
     for(count = 0; count < TX_RING_SIZE ;count++)\r
     {\r
@@ -1475,25 +1423,42 @@ static void MAC_memcpy(uint8_t *dest, const uint8_t *src, uint32_t n)
     }\r
 }\r
 \r
-void MSS_MAC_TxBufferCompleted( void )\r
+/***************************************************************************//**\r
+ * Check the buffers assigned to the Tx descriptors to ensure that none remain\r
+ * marked as in use even though the Tx has completed.  This could happen if a\r
+ * Tx interrupt was missed.\r
+ *\r
+ */\r
+void MSS_MAC_CheckTxBufferStatus( void )\r
 {\r
 unsigned char *pxTransmittedBuffer;\r
+long lDescriptor, lIndex;\r
 \r
-       /* Was it the second transmission that has completed? */\r
-       if( ( g_mss_mac.tx_descriptors[ 1 ].descriptor_0 & TDES0_OWN ) == 0UL )\r
+       for( lDescriptor = 1; lDescriptor < TX_RING_SIZE; lDescriptor++ )\r
        {\r
-               pxTransmittedBuffer = ( unsigned char * ) g_mss_mac.tx_descriptors[ 1 ].buffer_1;\r
+               if( ( g_mss_mac.tx_descriptors[ lDescriptor ].descriptor_0 & TDES0_OWN ) == 0UL )\r
+               {\r
+                       pxTransmittedBuffer = ( unsigned char * ) g_mss_mac.tx_descriptors[ lDescriptor ].buffer_1;\r
 \r
-               /* The buffer has been transmitted and is no longer in use. */\r
-               MAC_release_buffer( pxTransmittedBuffer );\r
-       }\r
-       else\r
-       {\r
-//             configASSERT( 0 );\r
+                       for( lIndex = 0; lIndex < macNUM_BUFFERS; lIndex++ )\r
+                       {\r
+                               if( pxTransmittedBuffer == &( xMACBuffers.ucBuffer[ lIndex ][ 0 ] ) )\r
+                               {\r
+                                       ucMACBufferInUse[ lIndex ] = pdFALSE;\r
+                               }\r
+                       }                       \r
+               }\r
        }\r
 }\r
 \r
-static unsigned char *MAC_obtain_buffer( void )\r
+/***************************************************************************//**\r
+ * Look through the array of buffers until one is found that is free for use -\r
+ * that is, not currently assigned to an Rx or a Tx descriptor.  Mark the buffer\r
+ * as in use, then return its address.\r
+ *\r
+ * @return          a pointer to a free buffer.\r
+ */\r
+unsigned char *MAC_obtain_buffer( void )\r
 {\r
 long lIndex;\r
 unsigned char *pcReturn = NULL;\r
@@ -1504,7 +1469,7 @@ unsigned char *pcReturn = NULL;
        {\r
                if( ucMACBufferInUse[ lIndex ] == pdFALSE )\r
                {\r
-                       pcReturn = &( ucMACBuffers[ lIndex ][ 0 ] );\r
+                       pcReturn = &( xMACBuffers.ucBuffer[ lIndex ][ 0 ] );\r
                        ucMACBufferInUse[ lIndex ] = pdTRUE;\r
                        break;\r
                }\r
@@ -1514,6 +1479,10 @@ unsigned char *pcReturn = NULL;
        return pcReturn;\r
 }\r
 \r
+/***************************************************************************//**\r
+ * Return a buffer to the list of free buffers, it was in use, but is not now.\r
+ *\r
+ */\r
 void MAC_release_buffer( unsigned char *pucBufferToRelease )\r
 {\r
 long lIndex;\r
@@ -1522,7 +1491,7 @@ long lIndex;
        it is currently pointing to is marked as being free again. */\r
        for( lIndex = 0; lIndex < macNUM_BUFFERS; lIndex++ )\r
        {\r
-               if( pucBufferToRelease == &( ucMACBuffers[ lIndex ][ 0 ] ) )\r
+               if( pucBufferToRelease == &( xMACBuffers.ucBuffer[ lIndex ][ 0 ] ) )\r
                {\r
                        /* This is the buffer in use, mark it as being free. */\r
                        ucMACBufferInUse[ lIndex ] = pdFALSE;\r
@@ -1530,6 +1499,10 @@ long lIndex;
                }\r
        }\r
        \r
+       /* Check the buffers pointed to by the Tx descriptors, just in case a Tx\r
+       interrupt has been missed and a free buffer remains marked as in use. */\r
+       MSS_MAC_CheckTxBufferStatus();\r
+       \r
        configASSERT( lIndex < macNUM_BUFFERS );\r
 }\r
 \r