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