Skip to content

Commit 9bd9d28

Browse files
htiboschHein Tiboschactions-userAniruddhaKanhere
authored
IPv4/single: SAME70 EMAC buffer sizes (#568)
* Implemented Maty's solution * Added a new statistic 'tx_write_fail' * Uncrustify: triggered by comment. * Increase NETWORK_BUFFER_SIZE in order to include the 'ipBUFFER_PADDING' bytes * ICMP checksum calculated manually * Uncrustify: triggered by comment. * Update gmac_SAM.c Co-authored-by: Hein Tibosch <[email protected]> Co-authored-by: GitHub Action <[email protected]> Co-authored-by: Aniruddha Kanhere <[email protected]>
1 parent ed04dc7 commit 9bd9d28

File tree

3 files changed

+68
-54
lines changed

3 files changed

+68
-54
lines changed

source/portable/NetworkInterface/DriverSAM/NetworkInterface.c

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,6 @@
7171
#define EMAC_IF_ERR_EVENT 4UL
7272
#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
7373

74-
/* 1536 bytes is more than needed, 1524 would be enough.
75-
* But 1536 is a multiple of 32, which gives a great alignment for
76-
* cached memories. */
77-
78-
#define NETWORK_BUFFER_SIZE 1536
79-
8074
#ifndef EMAC_MAX_BLOCK_TIME_MS
8175

8276
/* The task 'prvEMACHandlerTask()' will wake-up every 100 ms, to see
@@ -518,9 +512,10 @@ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescript
518512

519513
pxSendPacket = ( IPPacket_t * ) pxDescriptor->pucEthernetBuffer;
520514

521-
if( ulTransmitSize > NETWORK_BUFFER_SIZE )
515+
/* 'GMAC_TX_UNITSIZE' is the netto size of a transmission buffer. */
516+
if( ulTransmitSize > GMAC_TX_UNITSIZE )
522517
{
523-
ulTransmitSize = NETWORK_BUFFER_SIZE;
518+
ulTransmitSize = GMAC_TX_UNITSIZE;
524519
}
525520

526521
/* A do{}while(0) loop is introduced to allow the use of multiple break
@@ -566,7 +561,7 @@ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescript
566561
}
567562
#endif
568563

569-
ulResult = gmac_dev_write( &gs_gmac_dev, ( void * ) pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength );
564+
ulResult = gmac_dev_write( &gs_gmac_dev, ( void * ) pxDescriptor->pucEthernetBuffer, ulTransmitSize );
570565

571566
if( ulResult != GMAC_OK )
572567
{
@@ -742,17 +737,26 @@ void vGMACGenerateChecksum( uint8_t * pucBuffer,
742737
{
743738
ProtocolPacket_t * xProtPacket = ( ProtocolPacket_t * ) pucBuffer;
744739

745-
if( xProtPacket->xTCPPacket.xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE )
740+
/* The SAM4E has problems offloading checksums for transmission.
741+
* The SAME70 does not set the CRC for ICMP packets (ping). */
742+
743+
if( xProtPacket->xICMPPacket.xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE )
746744
{
747-
IPHeader_t * pxIPHeader = &( xProtPacket->xTCPPacket.xIPHeader );
745+
#if ( SAME70 != 0 )
746+
if( ( xProtPacket->xICMPPacket.xIPHeader.ucProtocol != ipPROTOCOL_UDP ) &&
747+
( xProtPacket->xICMPPacket.xIPHeader.ucProtocol != ipPROTOCOL_TCP ) )
748+
#endif
749+
{
750+
IPHeader_t * pxIPHeader = &( xProtPacket->xTCPPacket.xIPHeader );
748751

749-
/* Calculate the IP header checksum. */
750-
pxIPHeader->usHeaderChecksum = 0x00;
751-
pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
752-
pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
752+
/* Calculate the IP header checksum. */
753+
pxIPHeader->usHeaderChecksum = 0x00;
754+
pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
755+
pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
753756

754-
/* Calculate the TCP checksum for an outgoing packet. */
755-
usGenerateProtocolChecksum( pucBuffer, uxLength, pdTRUE );
757+
/* Calculate the TCP checksum for an outgoing packet. */
758+
usGenerateProtocolChecksum( pucBuffer, uxLength, pdTRUE );
759+
}
756760
}
757761
}
758762
/*-----------------------------------------------------------*/
@@ -773,7 +777,7 @@ static uint32_t prvEMACRxPoll( void )
773777
* descriptor then allocate one now. */
774778
if( ( pxNextNetworkBufferDescriptor == NULL ) && ( uxGetNumberOfFreeNetworkBuffers() > xMinDescriptorsToLeave ) )
775779
{
776-
pxNextNetworkBufferDescriptor = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, xBlockTime );
780+
pxNextNetworkBufferDescriptor = pxGetNetworkBufferWithDescriptor( GMAC_RX_UNITSIZE, xBlockTime );
777781
}
778782

779783
if( pxNextNetworkBufferDescriptor != NULL )
@@ -789,7 +793,7 @@ static uint32_t prvEMACRxPoll( void )
789793
}
790794

791795
/* Read the next packet from the hardware into pucUseBuffer. */
792-
ulResult = gmac_dev_read( &gs_gmac_dev, pucUseBuffer, ipTOTAL_ETHERNET_FRAME_SIZE, &ulReceiveCount, &pucDMABuffer );
796+
ulResult = gmac_dev_read( &gs_gmac_dev, pucUseBuffer, GMAC_RX_UNITSIZE, &ulReceiveCount, &pucDMABuffer );
793797

794798
if( ( ulResult != GMAC_OK ) || ( ulReceiveCount == 0 ) )
795799
{

source/portable/NetworkInterface/DriverSAM/gmac_SAM.c

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -111,17 +111,27 @@
111111
* See \ref gmac_quickstart.
112112
*
113113
* Driver for the GMAC (Ethernet Media Access Controller).
114-
* This file contains basic functions for the GMAC, with support for all modes, settings
115-
* and clock speeds.
114+
* This file contains basic functions for the GMAC, with support for all modes,
115+
* settings and clock speeds.
116116
*
117117
* \section dependencies Dependencies
118118
* This driver does not depend on other modules.
119119
*
120120
* @{
121121
*/
122122

123-
#define NETWORK_BUFFER_SIZE 1536
124-
123+
/*
124+
* When BufferAllocation_1.c is used, the network buffer space
125+
* is declared statically as 'ucNetworkPackets[]'.
126+
* Like the DMA descriptors, this array is located in a non-cached area.
127+
* Here an example of the total size:
128+
*
129+
* #define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 24
130+
* #define GMAC_FRAME_LENTGH_MAX 1536
131+
* Hidden space for back-pointer and IP-type 16
132+
*
133+
* Total size: 24 * ( 1536 + 16 ) = 37248 bytes
134+
*/
125135
__attribute__( ( aligned( 32 ) ) )
126136
__attribute__( ( section( ".first_data" ) ) )
127137
uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * NETWORK_BUFFER_SIZE ];
@@ -688,11 +698,6 @@ uint32_t gmac_dev_read( gmac_device_t * p_gmac_dev,
688698
return GMAC_OK;
689699
}
690700

691-
#if ( SAME70 == 0 )
692-
extern void vGMACGenerateChecksum( uint8_t * apBuffer,
693-
size_t uxLength );
694-
#endif
695-
696701
/**
697702
* \brief Send ulLength bytes from pcFrom. This copies the buffer to one of the
698703
* GMAC Tx buffers, and then indicates to the GMAC that the buffer is ready.
@@ -749,13 +754,10 @@ uint32_t gmac_dev_write( gmac_device_t * p_gmac_dev,
749754
memcpy( ( void * ) p_tx_td->addr, p_buffer, ul_size );
750755
}
751756
#endif /* ipconfigZERO_COPY_TX_DRIVER */
752-
#if ( SAME70 == 0 )
753-
{
754-
#warning Is this a SAM4E?
755-
/* Needs to be called for SAM4E series only. */
756-
vGMACGenerateChecksum( ( uint8_t * ) p_tx_td->addr, ( size_t ) ul_size );
757-
}
758-
#endif
757+
{
758+
/* Needs to be called for SAM4E series only. */
759+
vGMACGenerateChecksum( ( uint8_t * ) p_tx_td->addr, ( size_t ) ul_size );
760+
}
759761
}
760762

761763
/* Update transmit descriptor status */

source/portable/NetworkInterface/DriverSAM/gmac_SAM.h

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -96,42 +96,45 @@
9696

9797
/** The MAC can support frame lengths up to 1536 bytes */
9898
#define GMAC_FRAME_LENTGH_MAX 1536
99+
#define GMAC_RX_UNITSIZE GMAC_FRAME_LENTGH_MAX /**< Maximum size for RX buffer */
100+
#define GMAC_TX_UNITSIZE GMAC_FRAME_LENTGH_MAX /**< Maximum size for TX buffer */
99101

100-
/*#define GMAC_RX_UNITSIZE 128 / **< Fixed size for RX buffer * / */
101-
#define GMAC_RX_UNITSIZE 1536 /**< Fixed size for RX buffer */
102+
/* A network buffer starts with 10 hidden bytes (ipBUFFER_PADDING)
103+
* in which a pointer is stored. Round up this extra size to a multiple of 16,
104+
* in order to get well-aligned buffers. */
102105

103-
/*#define GMAC_TX_UNITSIZE 1518 / **< Size for ETH frame length * / */
104-
#define GMAC_TX_UNITSIZE 1536 /**< Size for ETH frame length */
106+
#define BUFFER_PADDING ( ( ipBUFFER_PADDING + 16U ) & ~0x0FU )
107+
#define NETWORK_BUFFER_SIZE ( GMAC_FRAME_LENTGH_MAX + BUFFER_PADDING )
105108

106109
/** GMAC clock speed */
107-
#define GMAC_MCK_SPEED_240MHZ ( 240 * 1000 * 1000 )
108-
#define GMAC_MCK_SPEED_160MHZ ( 160 * 1000 * 1000 )
109-
#define GMAC_MCK_SPEED_120MHZ ( 120 * 1000 * 1000 )
110-
#define GMAC_MCK_SPEED_80MHZ ( 80 * 1000 * 1000 )
111-
#define GMAC_MCK_SPEED_40MHZ ( 40 * 1000 * 1000 )
112-
#define GMAC_MCK_SPEED_20MHZ ( 20 * 1000 * 1000 )
110+
#define GMAC_MCK_SPEED_240MHZ ( 240 * 1000 * 1000 )
111+
#define GMAC_MCK_SPEED_160MHZ ( 160 * 1000 * 1000 )
112+
#define GMAC_MCK_SPEED_120MHZ ( 120 * 1000 * 1000 )
113+
#define GMAC_MCK_SPEED_80MHZ ( 80 * 1000 * 1000 )
114+
#define GMAC_MCK_SPEED_40MHZ ( 40 * 1000 * 1000 )
115+
#define GMAC_MCK_SPEED_20MHZ ( 20 * 1000 * 1000 )
113116

114117
/** GMAC maintain code default value*/
115-
#define GMAC_MAN_CODE_VALUE ( 10 )
118+
#define GMAC_MAN_CODE_VALUE ( 10 )
116119

117120
/** GMAC maintain start of frame default value*/
118-
#define GMAC_MAN_SOF_VALUE ( 1 )
121+
#define GMAC_MAN_SOF_VALUE ( 1 )
119122

120123
/** GMAC maintain read/write*/
121-
#define GMAC_MAN_RW_TYPE ( 2 )
124+
#define GMAC_MAN_RW_TYPE ( 2 )
122125

123126
/** GMAC maintain read only*/
124-
#define GMAC_MAN_READ_ONLY ( 1 )
127+
#define GMAC_MAN_READ_ONLY ( 1 )
125128

126129
/** GMAC address length */
127-
#define GMAC_ADDR_LENGTH ( 6 )
130+
#define GMAC_ADDR_LENGTH ( 6 )
128131

129132

130-
#define GMAC_DUPLEX_HALF 0
131-
#define GMAC_DUPLEX_FULL 1
133+
#define GMAC_DUPLEX_HALF 0
134+
#define GMAC_DUPLEX_FULL 1
132135

133-
#define GMAC_SPEED_10M 0
134-
#define GMAC_SPEED_100M 1
136+
#define GMAC_SPEED_10M 0
137+
#define GMAC_SPEED_100M 1
135138

136139
/**
137140
* \brief Return codes for GMAC APIs.
@@ -1536,6 +1539,11 @@
15361539

15371540
void gmac_reset_tx_mem( gmac_device_t * p_dev );
15381541

1542+
/* The SAM4E has problems offloading checksums for transmission.
1543+
* The SAME70 does not set the CRC for ICMP packets (ping). */
1544+
extern void vGMACGenerateChecksum( uint8_t * apBuffer,
1545+
size_t uxLength );
1546+
15391547
/*/ @cond 0 */
15401548
/**INDENT-OFF**/
15411549
#ifdef __cplusplus

0 commit comments

Comments
 (0)