*\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
/* 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
/*\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
#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
\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
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
/* 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
/* 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
{\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
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
{\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
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
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
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
\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
}\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
(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
)\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
* 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
{\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
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
/***************************************************************************//**\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
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
\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
{\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
)\r
{\r
int32_t link;\r
- configASSERT( MAC_test_instance() == MAC_OK );\r
\r
PHY_auto_negotiate();\r
\r
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
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
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
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
\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
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
{\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
)\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
\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
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
\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
\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
{\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
{\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
{\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
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
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
}\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
{\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
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
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
}\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