Add STM32 Ethernet packet reception logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4160 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
fc91fdd727
commit
8c1436b4a6
@ -46,6 +46,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <wdog.h>
|
#include <wdog.h>
|
||||||
|
#include <queue.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
@ -139,19 +140,26 @@
|
|||||||
#undef CONFIG_STM32_ETH_ENHANCEDDESC
|
#undef CONFIG_STM32_ETH_ENHANCEDDESC
|
||||||
#undef CONFIG_STM32_ETH_HWCHECKSUM
|
#undef CONFIG_STM32_ETH_HWCHECKSUM
|
||||||
|
|
||||||
/* Ethernet buffer sizes and numbers */
|
/* Ethernet buffer sizes, nubmer of buffers, and number of descriptors */
|
||||||
|
|
||||||
#ifndef CONFIG_STM32_ETH_RXBUFSIZE
|
#ifndef CONFIG_NET_MULTIBUFFER
|
||||||
# define CONFIG_STM32_ETH_RXBUFSIZE CONFIG_NET_BUFSIZE
|
# error "CONFIG_NET_MULTIBUFFER is required"
|
||||||
#endif
|
#endif
|
||||||
#ifndef CONFIG_STM32_ETH_TXBUFSIZE
|
|
||||||
# define CONFIG_STM32_ETH_TXBUFSIZE CONFIG_NET_BUFSIZE
|
#ifndef CONFIG_STM32_ETH_BUFSIZE
|
||||||
|
# define CONFIG_STM32_ETH_BUFSIZE CONFIG_NET_BUFSIZE
|
||||||
#endif
|
#endif
|
||||||
#ifndef CONFIG_STM32_ETH_RXNBUFFERS
|
#ifndef CONFIG_STM32_ETH_NRXDESC
|
||||||
# define CONFIG_STM32_ETH_RXNBUFFERS 20
|
# define CONFIG_STM32_ETH_NRXDESC 8
|
||||||
#endif
|
#endif
|
||||||
#ifndef CONFIG_STM32_ETH_TXNBUFFERS
|
#ifndef CONFIG_STM32_ETH_NTXDESC
|
||||||
# define CONFIG_STM32_ETH_TXNBUFFERS 5
|
# define CONFIG_STM32_ETH_NTXDESC 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_STM32_ETH_NTXDESC > 2
|
||||||
|
# define STM32_ETH_NFREEBUFFERS CONFIG_STM32_ETH_NTXDESC
|
||||||
|
#else
|
||||||
|
# define STM32_ETH_NFREEBUFFERS 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Clocking *****************************************************************/
|
/* Clocking *****************************************************************/
|
||||||
@ -463,48 +471,39 @@
|
|||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
struct eth_rxframe_info_s
|
|
||||||
{
|
|
||||||
volatile struct stm2_ethdesc_s *rxfirst; /* First Segment Rx Desc */
|
|
||||||
volatile struct stm2_ethdesc_s *rxlast; /* Last Segment Rx Desc */
|
|
||||||
volatile uint32_t segcount; /* Segment count */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The stm32_ethmac_s encapsulates all state information for a single hardware
|
/* The stm32_ethmac_s encapsulates all state information for a single hardware
|
||||||
* interface
|
* interface
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct stm32_ethmac_s
|
struct stm32_ethmac_s
|
||||||
{
|
{
|
||||||
uint8_t ifup : 1; /* true:ifup false:ifdown */
|
uint8_t ifup : 1; /* true:ifup false:ifdown */
|
||||||
uint8_t mbps100 : 1; /* 100MBps operation (vs 10 MBps) */
|
uint8_t mbps100 : 1; /* 100MBps operation (vs 10 MBps) */
|
||||||
uint8_t fduplex : 1; /* Full (vs. half) duplex */
|
uint8_t fduplex : 1; /* Full (vs. half) duplex */
|
||||||
WDOG_ID txpoll; /* TX poll timer */
|
WDOG_ID txpoll; /* TX poll timer */
|
||||||
WDOG_ID txtimeout; /* TX timeout timer */
|
WDOG_ID txtimeout; /* TX timeout timer */
|
||||||
|
|
||||||
/* This holds the information visible to uIP/NuttX */
|
/* This holds the information visible to uIP/NuttX */
|
||||||
|
|
||||||
struct uip_driver_s dev; /* Interface understood by uIP */
|
struct uip_driver_s dev; /* Interface understood by uIP */
|
||||||
|
|
||||||
/* Used to track transmit and receive descriptors */
|
/* Used to track transmit and receive descriptors */
|
||||||
|
|
||||||
volatile struct eth_txdesc_s *txdesc;
|
struct eth_txdesc_s *txdesc; /* Next TX descriptor */
|
||||||
volatile struct eth_rxdesc_s *rxdesc;
|
struct eth_rxdesc_s *rxdesc; /* Next RX descriptor */
|
||||||
|
struct eth_rxdesc_s *rxfirst; /* First RX descriptor of the segment */
|
||||||
/* Frame info */
|
uint32_t segcount; /* Segment count */
|
||||||
|
sq_queue_t freeb; /* The free buffer list */
|
||||||
struct eth_rxframe_info_s rxframe;
|
|
||||||
volatile struct eth_rxframe_info_s *rxframeinfo;
|
|
||||||
|
|
||||||
/* Descriptor allocations */
|
/* Descriptor allocations */
|
||||||
|
|
||||||
struct eth_rxdesc_s rxtable[CONFIG_STM32_ETH_RXNBUFFERS];
|
struct eth_rxdesc_s rxtable[CONFIG_STM32_ETH_NRXDESC];
|
||||||
struct eth_txdesc_s txtable[CONFIG_STM32_ETH_TXNBUFFERS];
|
struct eth_txdesc_s txtable[CONFIG_STM32_ETH_NTXDESC];
|
||||||
|
|
||||||
/* Buffer allocations */
|
/* Buffer allocations */
|
||||||
|
|
||||||
uint8_t rxbuffer[CONFIG_STM32_ETH_RXNBUFFERS*CONFIG_STM32_ETH_RXBUFSIZE];
|
uint8_t rxbuffer[CONFIG_STM32_ETH_NRXDESC*CONFIG_STM32_ETH_BUFSIZE];
|
||||||
uint8_t txbuffer[CONFIG_STM32_ETH_TXNBUFFERS*CONFIG_STM32_ETH_TXBUFSIZE];
|
uint8_t alloc[STM32_ETH_NFREEBUFFERS*CONFIG_STM32_ETH_BUFSIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -516,6 +515,12 @@ static struct stm32_ethmac_s g_stm32ethmac[STM32_NETHERNET];
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
/* Free buffer management */
|
||||||
|
|
||||||
|
static void stm32_initbuffer(FAR struct stm32_ethmac_s *priv);
|
||||||
|
static inline uint8_t *stm32_allocbuffer(FAR struct stm32_ethmac_s *priv);
|
||||||
|
static inline void stm32_freebuffer(FAR struct stm32_ethmac_s *priv, uint8_t *buffer);
|
||||||
|
static inline bool stm32_isfreebuffer(FAR struct stm32_ethmac_s *priv);
|
||||||
|
|
||||||
/* Common TX logic */
|
/* Common TX logic */
|
||||||
|
|
||||||
@ -524,6 +529,9 @@ static int stm32_uiptxpoll(struct uip_driver_s *dev);
|
|||||||
|
|
||||||
/* Interrupt handling */
|
/* Interrupt handling */
|
||||||
|
|
||||||
|
static void stm32_freesegment(FAR struct stm32_ethmac_s *priv,
|
||||||
|
FAR struct eth_rxdesc_s *rxfirst, int nsegments);
|
||||||
|
static int stm32_recvframe(FAR struct stm32_ethmac_s *priv);
|
||||||
static void stm32_receive(FAR struct stm32_ethmac_s *priv);
|
static void stm32_receive(FAR struct stm32_ethmac_s *priv);
|
||||||
static void stm32_txdone(FAR struct stm32_ethmac_s *priv);
|
static void stm32_txdone(FAR struct stm32_ethmac_s *priv);
|
||||||
static int stm32_interrupt(int irq, FAR void *context);
|
static int stm32_interrupt(int irq, FAR void *context);
|
||||||
@ -566,6 +574,111 @@ static int stm32_ethconfig(FAR struct stm32_ethmac_s *priv);
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: stm32_initbuffer
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize the free buffer list.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* priv - Reference to the driver state structure
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* Called during early driver initialization before Ethernet interrupts
|
||||||
|
* are enabled.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void stm32_initbuffer(FAR struct stm32_ethmac_s *priv)
|
||||||
|
{
|
||||||
|
uint8_t *buffer;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sq_init(&priv->freeb);
|
||||||
|
|
||||||
|
for (i = 0, buffer = priv->alloc;
|
||||||
|
i < STM32_ETH_NFREEBUFFERS;
|
||||||
|
i++, buffer += CONFIG_STM32_ETH_BUFSIZE)
|
||||||
|
{
|
||||||
|
sq_addlast((FAR sq_entry_t *)buffer, &priv->freeb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: stm32_allocbuffer
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Allocate one buffer from the free buffer list.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* priv - Reference to the driver state structure
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Pointer to the allocated buffer on success; NULL on failure
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* May or may not be called from an interrupt handler. In either case,
|
||||||
|
* global interrupts are disabled, either explicitly or indirectly through
|
||||||
|
* interrupt handling logic.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline uint8_t *stm32_allocbuffer(FAR struct stm32_ethmac_s *priv)
|
||||||
|
{
|
||||||
|
return (uint8_t *)sq_remfirst(&priv->freeb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: stm32_freebuffer
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Return a buffer to the free buffer list.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* priv - Reference to the driver state structure
|
||||||
|
* buffer - A pointer to the buffer to be freed
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* May or may not be called from an interrupt handler. In either case,
|
||||||
|
* global interrupts are disabled, either explicitly or indirectly through
|
||||||
|
* interrupt handling logic.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline void stm32_freebuffer(FAR struct stm32_ethmac_s *priv, uint8_t *buffer)
|
||||||
|
{
|
||||||
|
sq_addlast((FAR sq_entry_t *)buffer, &priv->freeb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: stm32_isfreebuffer
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Return TRUE if the free buffer list is not empty.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* priv - Reference to the driver state structure
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* True if there are one or more buffers in the free buffer list;
|
||||||
|
* false if the free buffer list is empty
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline bool stm32_isfreebuffer(FAR struct stm32_ethmac_s *priv)
|
||||||
|
{
|
||||||
|
return !sq_empty(&priv->freeb);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: stm32_transmit
|
* Function: stm32_transmit
|
||||||
*
|
*
|
||||||
@ -660,6 +773,197 @@ static int stm32_uiptxpoll(struct uip_driver_s *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: stm32_freesegment
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The function is called when a frame is received using the DMA receive
|
||||||
|
* interrupt. It scans the RX descriptors to the the received frame.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* priv - Reference to the driver state structure
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* Global interrupts are disabled by interrupt handling logic.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void stm32_freesegment(FAR struct stm32_ethmac_s *priv,
|
||||||
|
FAR struct eth_rxdesc_s *rxfirst, int nsegments)
|
||||||
|
{
|
||||||
|
struct eth_rxdesc_s *rxdesc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Set OWN bit in RX descriptors. This gives the buffers back to DMA */
|
||||||
|
|
||||||
|
rxdesc = rxfirst;
|
||||||
|
for (i = 0; i < nsegments; i++)
|
||||||
|
{
|
||||||
|
rxdesc->rdes0 = ETH_RDES0_OWN;
|
||||||
|
rxdesc = (struct eth_rxdesc_s *)rxdesc->rdes3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the segment managment logic */
|
||||||
|
|
||||||
|
priv->rxfirst = NULL;
|
||||||
|
priv->segcount = 0;
|
||||||
|
|
||||||
|
/* Check if the RX Buffer unavailable flag is set */
|
||||||
|
|
||||||
|
if ((getreg32(STM32_ETH_DMASR) & ETH_DMAINT_RBUI) != 0)
|
||||||
|
{
|
||||||
|
/* Clear RBUS Ethernet DMA flag */
|
||||||
|
|
||||||
|
putreg32(ETH_DMAINT_RBUI, STM32_ETH_DMASR);
|
||||||
|
|
||||||
|
/* Resume DMA reception */
|
||||||
|
|
||||||
|
putreg32(0, STM32_ETH_DMARPDR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: stm32_recvframe
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* The function is called when a frame is received using the DMA receive
|
||||||
|
* interrupt. It scans the RX descriptors of the received frame.
|
||||||
|
*
|
||||||
|
* NOTE: This function will silently discard any packets containing errors.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* priv - Reference to the driver state structure
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* OK if a packet was successfully returned; -EAGAIN if there are no
|
||||||
|
* further packets available
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* Global interrupts are disabled by interrupt handling logic.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int stm32_recvframe(FAR struct stm32_ethmac_s *priv)
|
||||||
|
{
|
||||||
|
struct eth_rxdesc_s *rxdesc;
|
||||||
|
struct eth_rxdesc_s *rxfirst;
|
||||||
|
uint8_t *buffer;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Check if there are free buffers. We cannot receive new frames in this
|
||||||
|
* design unless there is at least one free buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!stm32_isfreebuffer(priv))
|
||||||
|
{
|
||||||
|
nlldbg("No free buffers\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scan descriptors owned by the CPU */
|
||||||
|
|
||||||
|
rxdesc = priv->rxdesc;
|
||||||
|
for (i = 0;
|
||||||
|
(rxdesc->rdes0 & ETH_RDES0_OWN) == 0 && i < CONFIG_STM32_ETH_NRXDESC;
|
||||||
|
i++)
|
||||||
|
{
|
||||||
|
/* Check if this is the first segment in the frame */
|
||||||
|
|
||||||
|
if ((rxdesc->rdes0 & ETH_RDES0_FS) != 0 &&
|
||||||
|
(rxdesc->rdes0 & ETH_RDES0_LS) == 0)
|
||||||
|
{
|
||||||
|
priv->rxfirst = rxdesc;
|
||||||
|
priv->segcount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if this is an intermediate segment in the frame */
|
||||||
|
|
||||||
|
else if (((rxdesc->rdes0 & ETH_RDES0_LS) == 0)&&
|
||||||
|
((rxdesc->rdes0 & ETH_RDES0_FS) == 0))
|
||||||
|
{
|
||||||
|
priv->segcount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, it is the last segment in the frame */
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
priv->segcount++;
|
||||||
|
|
||||||
|
/* Check if the there is only one segment in the frame */
|
||||||
|
|
||||||
|
if (priv->segcount == 1)
|
||||||
|
{
|
||||||
|
rxfirst = rxdesc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rxfirst = priv->rxfirst;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if any errors are reported in the frame */
|
||||||
|
|
||||||
|
if ((rxdesc->rdes0 & ETH_RDES0_ES) == 0)
|
||||||
|
{
|
||||||
|
struct uip_driver_s *dev = &priv->dev;
|
||||||
|
|
||||||
|
/* Get the Frame Length of the received packet: substruct 4
|
||||||
|
* bytes of the CRC
|
||||||
|
*/
|
||||||
|
|
||||||
|
dev->d_len = ((rxdesc->rdes0 & ETH_RDES0_FL_MASK) >> ETH_RDES0_FL_SHIFT) - 4;
|
||||||
|
|
||||||
|
/* Get a buffer from the free list. We don't even check if
|
||||||
|
* this is successful because we already assure the the free
|
||||||
|
* list is not empty above.
|
||||||
|
*/
|
||||||
|
|
||||||
|
buffer = stm32_allocbuffer(priv);
|
||||||
|
|
||||||
|
/* Take the buffer from the RX descriptor of the first free
|
||||||
|
* segment, put it into the uIP device structure, then replace
|
||||||
|
* the buffer in the RX descriptor with the newly allocated
|
||||||
|
* buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dev->d_buf = (uint8_t*)rxfirst->rdes2;
|
||||||
|
rxfirst->rdes2 = (uint32_t)buffer;
|
||||||
|
|
||||||
|
/* Return success, remebering where we should re-start scanning
|
||||||
|
* and resetting the segment scanning logic
|
||||||
|
*/
|
||||||
|
|
||||||
|
priv->rxdesc = (struct eth_rxdesc_s*)rxdesc->rdes3;
|
||||||
|
stm32_freesegment(priv, rxfirst, priv->segcount);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Drop the frame that contains the errors, reset the segment
|
||||||
|
* scanning logic, and continue scanning with the next frame.
|
||||||
|
*/
|
||||||
|
|
||||||
|
nlldbg("DROPPED: RX descriptor errors: %08x\n", rxdesc->rdes0);
|
||||||
|
stm32_freesegment(priv, rxfirst, priv->segcount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try the next descriptor */
|
||||||
|
|
||||||
|
rxdesc = (struct eth_rxdesc_s*)rxdesc->rdes3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We get here after all of the descriptors have been scanned. Remember
|
||||||
|
* where we left off.
|
||||||
|
*/
|
||||||
|
|
||||||
|
priv->rxdesc = rxdesc;
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: stm32_receive
|
* Function: stm32_receive
|
||||||
*
|
*
|
||||||
@ -679,16 +983,23 @@ static int stm32_uiptxpoll(struct uip_driver_s *dev)
|
|||||||
|
|
||||||
static void stm32_receive(FAR struct stm32_ethmac_s *priv)
|
static void stm32_receive(FAR struct stm32_ethmac_s *priv)
|
||||||
{
|
{
|
||||||
do
|
struct uip_driver_s *dev = &priv->dev;
|
||||||
|
|
||||||
|
/* Loop while while stm32_recvframe() successfully retrieves valid
|
||||||
|
* Ethernet frames.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (stm32_recvframe(priv) == OK)
|
||||||
{
|
{
|
||||||
/* Check for errors and update statistics */
|
/* Check if the packet is a valid size for the uIP buffer configuration
|
||||||
|
* (this should not happen)
|
||||||
/* Check if the packet is a valid size for the uIP buffer configuration */
|
|
||||||
|
|
||||||
/* Copy the data data from the hardware to priv->dev.d_buf. Set
|
|
||||||
* amount of data in priv->dev.d_len
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (dev->d_len > CONFIG_NET_BUFSIZE)
|
||||||
|
{
|
||||||
|
nlldbg("DROPPED: Too big: %d\n", dev->d_len);
|
||||||
|
}
|
||||||
|
|
||||||
/* We only accept IP packets of the configured type and ARP packets */
|
/* We only accept IP packets of the configured type and ARP packets */
|
||||||
|
|
||||||
#ifdef CONFIG_NET_IPv6
|
#ifdef CONFIG_NET_IPv6
|
||||||
@ -724,7 +1035,6 @@ static void stm32_receive(FAR struct stm32_ethmac_s *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (false); /* While there are more packets to be processed */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1151,7 +1461,7 @@ static void stm32_txdescinit(FAR struct stm32_ethmac_s *priv)
|
|||||||
|
|
||||||
/* Initialize each TX descriptor */
|
/* Initialize each TX descriptor */
|
||||||
|
|
||||||
for (i = 0; i < CONFIG_STM32_ETH_TXNBUFFERS; i++)
|
for (i = 0; i < CONFIG_STM32_ETH_NTXDESC; i++)
|
||||||
{
|
{
|
||||||
txdesc = &priv->txtable[i];
|
txdesc = &priv->txtable[i];
|
||||||
|
|
||||||
@ -1159,13 +1469,21 @@ static void stm32_txdescinit(FAR struct stm32_ethmac_s *priv)
|
|||||||
|
|
||||||
txdesc->tdes0 = ETH_TDES0_TCH;
|
txdesc->tdes0 = ETH_TDES0_TCH;
|
||||||
|
|
||||||
/* Set Buffer1 address pointer */
|
#ifdef CHECKSUM_BY_HARDWARE
|
||||||
|
/* Enable the checksum insertion for the Tx frames */
|
||||||
|
|
||||||
txdesc->tdes2 = (uint32_t)(&priv->txbuffer[i*CONFIG_STM32_ETH_TXBUFSIZE]);
|
txdesc->tdes0 |= ETH_TDES0_CIC_ALL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Clear Buffer1 address pointer (buffers will be assigned as they
|
||||||
|
* are used)
|
||||||
|
*/
|
||||||
|
|
||||||
|
txdesc->tdes2 = 0;;
|
||||||
|
|
||||||
/* Initialize the next descriptor with the Next Descriptor Polling Enable */
|
/* Initialize the next descriptor with the Next Descriptor Polling Enable */
|
||||||
|
|
||||||
if( i < (CONFIG_STM32_ETH_TXNBUFFERS-1))
|
if( i < (CONFIG_STM32_ETH_NTXDESC-1))
|
||||||
{
|
{
|
||||||
/* Set next descriptor address register with next descriptor base
|
/* Set next descriptor address register with next descriptor base
|
||||||
* address
|
* address
|
||||||
@ -1182,6 +1500,10 @@ static void stm32_txdescinit(FAR struct stm32_ethmac_s *priv)
|
|||||||
txdesc->tdes3 = (uint32_t)priv->txtable;
|
txdesc->tdes3 = (uint32_t)priv->txtable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set Transmit Desciptor List Address Register */
|
||||||
|
|
||||||
|
putreg32((uint32_t)priv->txtable, STM32_ETH_DMATDLAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1211,7 +1533,7 @@ static void stm32_rxdescinit(FAR struct stm32_ethmac_s *priv)
|
|||||||
|
|
||||||
/* Initialize each TX descriptor */
|
/* Initialize each TX descriptor */
|
||||||
|
|
||||||
for (i = 0; i < CONFIG_STM32_ETH_RXNBUFFERS; i++)
|
for (i = 0; i < CONFIG_STM32_ETH_NRXDESC; i++)
|
||||||
{
|
{
|
||||||
rxdesc = &priv->rxtable[i];
|
rxdesc = &priv->rxtable[i];
|
||||||
|
|
||||||
@ -1219,17 +1541,19 @@ static void stm32_rxdescinit(FAR struct stm32_ethmac_s *priv)
|
|||||||
|
|
||||||
rxdesc->rdes0 = ETH_RDES0_OWN;
|
rxdesc->rdes0 = ETH_RDES0_OWN;
|
||||||
|
|
||||||
/* Set Buffer1 size and Second Address Chained bit */
|
/* Set Buffer1 size and Second Address Chained bit and enabled DMA
|
||||||
|
* RX desc receive interrupt
|
||||||
|
*/
|
||||||
|
|
||||||
rxdesc->rdes1 = ETH_RDES1_RCH | (uint32_t)CONFIG_STM32_ETH_RXBUFSIZE;
|
rxdesc->rdes1 = ETH_RDES1_RCH | (uint32_t)CONFIG_STM32_ETH_BUFSIZE;
|
||||||
|
|
||||||
/* Set Buffer1 address pointer */
|
/* Set Buffer1 address pointer */
|
||||||
|
|
||||||
rxdesc->rdes2 = (uint32_t)&priv->rxbuffer[i*CONFIG_STM32_ETH_RXBUFSIZE];
|
rxdesc->rdes2 = (uint32_t)&priv->rxbuffer[i*CONFIG_STM32_ETH_BUFSIZE];
|
||||||
|
|
||||||
/* Initialize the next descriptor with the Next Descriptor Polling Enable */
|
/* Initialize the next descriptor with the Next Descriptor Polling Enable */
|
||||||
|
|
||||||
if( i < (CONFIG_STM32_ETH_RXNBUFFERS-1))
|
if( i < (CONFIG_STM32_ETH_NRXDESC-1))
|
||||||
{
|
{
|
||||||
/* Set next descriptor address register with next descriptor base
|
/* Set next descriptor address register with next descriptor base
|
||||||
* address
|
* address
|
||||||
@ -1250,8 +1574,6 @@ static void stm32_rxdescinit(FAR struct stm32_ethmac_s *priv)
|
|||||||
/* Set Receive Descriptor List Address Register */
|
/* Set Receive Descriptor List Address Register */
|
||||||
|
|
||||||
putreg32((uint32_t)priv->rxtable, STM32_ETH_DMARDLAR);
|
putreg32((uint32_t)priv->rxtable, STM32_ETH_DMARDLAR);
|
||||||
|
|
||||||
priv->rxframeinfo = &priv->rxframe;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1776,31 +2098,7 @@ static int stm32_macconfig(FAR struct stm32_ethmac_s *priv)
|
|||||||
static int stm32_macenable(FAR struct stm32_ethmac_s *priv)
|
static int stm32_macenable(FAR struct stm32_ethmac_s *priv)
|
||||||
{
|
{
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Enable Ethernet Rx interrrupt */
|
|
||||||
|
|
||||||
for (i = 0; i < CONFIG_STM32_ETH_RXNBUFFERS; i++)
|
|
||||||
{
|
|
||||||
/* Enable the DMA Rx Desc receive interrupt */
|
|
||||||
|
|
||||||
priv->rxtable[i].rdes1 &= ~ETH_RDES1_DIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CHECKSUM_BY_HARDWARE
|
|
||||||
/* Enable the checksum insertion for the Tx frames */
|
|
||||||
|
|
||||||
for (i = 0; i < CONFIG_STM32_ETH_TXNBUFFERS; i++)
|
|
||||||
{
|
|
||||||
/* Set the selected DMA Tx desc checksum insertion control */
|
|
||||||
|
|
||||||
priv->txtable[i].tdes0 |= ETH_TDES0_CIC_ALL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Enable RX and TX */
|
|
||||||
#warning "Missing Logic"
|
|
||||||
|
|
||||||
/* Enable transmit state machine of the MAC for transmission on the MII */
|
/* Enable transmit state machine of the MAC for transmission on the MII */
|
||||||
|
|
||||||
regval = getreg32(STM32_ETH_MACCR);
|
regval = getreg32(STM32_ETH_MACCR);
|
||||||
@ -1901,6 +2199,10 @@ static int stm32_ethconfig(FAR struct stm32_ethmac_s *priv)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize the free buffer list */
|
||||||
|
|
||||||
|
stm32_initbuffer(priv);
|
||||||
|
|
||||||
/* Initialize Tx Descriptors list: Chain Mode */
|
/* Initialize Tx Descriptors list: Chain Mode */
|
||||||
|
|
||||||
stm32_txdescinit(priv);
|
stm32_txdescinit(priv);
|
||||||
|
@ -686,6 +686,8 @@ CONFIG_MMCSD_HAVECARDDETECT=n
|
|||||||
# TCP/IP and UDP support via uIP
|
# TCP/IP and UDP support via uIP
|
||||||
#
|
#
|
||||||
# CONFIG_NET - Enable or disable all network features
|
# CONFIG_NET - Enable or disable all network features
|
||||||
|
# CONFIG_NET_NOINTS - uIP not called from interrupt level.
|
||||||
|
# CONFIG_NET_MULTIBUFFER - Use multiple input/output buffers (probably no)
|
||||||
# CONFIG_NET_IPv6 - Build in support for IPv6
|
# CONFIG_NET_IPv6 - Build in support for IPv6
|
||||||
# CONFIG_NSOCKET_DESCRIPTORS - Maximum number of socket descriptors per task/thread.
|
# CONFIG_NSOCKET_DESCRIPTORS - Maximum number of socket descriptors per task/thread.
|
||||||
# CONFIG_NET_SOCKOPTS - Enable or disable support for socket options
|
# CONFIG_NET_SOCKOPTS - Enable or disable support for socket options
|
||||||
@ -710,6 +712,8 @@ CONFIG_MMCSD_HAVECARDDETECT=n
|
|||||||
# CONFIG_NET_FWCACHE_SIZE - number of packets to remember when looking for duplicates
|
# CONFIG_NET_FWCACHE_SIZE - number of packets to remember when looking for duplicates
|
||||||
#
|
#
|
||||||
CONFIG_NET=n
|
CONFIG_NET=n
|
||||||
|
CONFIG_NET_NOINTS=n
|
||||||
|
CONFIG_NET_MULTIBUFFER=y
|
||||||
CONFIG_NET_IPv6=n
|
CONFIG_NET_IPv6=n
|
||||||
CONFIG_NSOCKET_DESCRIPTORS=10
|
CONFIG_NSOCKET_DESCRIPTORS=10
|
||||||
CONFIG_NET_SOCKOPTS=y
|
CONFIG_NET_SOCKOPTS=y
|
||||||
|
@ -650,6 +650,8 @@ CONFIG_MMCSD_HAVECARDDETECT=n
|
|||||||
#
|
#
|
||||||
# TCP/IP and UDP support via uIP
|
# TCP/IP and UDP support via uIP
|
||||||
# CONFIG_NET - Enable or disable all network features
|
# CONFIG_NET - Enable or disable all network features
|
||||||
|
# CONFIG_NET_NOINTS - uIP not called from interrupt level.
|
||||||
|
# CONFIG_NET_MULTIBUFFER - Use multiple input/output buffers (probably no)
|
||||||
# CONFIG_NET_IPv6 - Build in support for IPv6
|
# CONFIG_NET_IPv6 - Build in support for IPv6
|
||||||
# CONFIG_NSOCKET_DESCRIPTORS - Maximum number of socket descriptors per task/thread.
|
# CONFIG_NSOCKET_DESCRIPTORS - Maximum number of socket descriptors per task/thread.
|
||||||
# CONFIG_NET_SOCKOPTS - Enable or disable support for socket options
|
# CONFIG_NET_SOCKOPTS - Enable or disable support for socket options
|
||||||
@ -674,6 +676,8 @@ CONFIG_MMCSD_HAVECARDDETECT=n
|
|||||||
# CONFIG_NET_FWCACHE_SIZE - number of packets to remember when looking for duplicates
|
# CONFIG_NET_FWCACHE_SIZE - number of packets to remember when looking for duplicates
|
||||||
#
|
#
|
||||||
CONFIG_NET=n
|
CONFIG_NET=n
|
||||||
|
CONFIG_NET_NOINTS=n
|
||||||
|
CONFIG_NET_MULTIBUFFER=y
|
||||||
CONFIG_NET_IPv6=n
|
CONFIG_NET_IPv6=n
|
||||||
CONFIG_NSOCKET_DESCRIPTORS=0
|
CONFIG_NSOCKET_DESCRIPTORS=0
|
||||||
CONFIG_NET_SOCKOPTS=y
|
CONFIG_NET_SOCKOPTS=y
|
||||||
|
Loading…
Reference in New Issue
Block a user