mirror of
https://github.com/apache/nuttx.git
synced 2026-05-20 04:16:35 +08:00
Eliminate CONFIG_NO_NOINTS. Lots of files changed -> lots of testing needed.
This commit is contained in:
@@ -59,11 +59,7 @@
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
|
||||
@@ -84,13 +80,12 @@
|
||||
* is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# error Work queue support is required in this configuration (CONFIG_SCHED_WORKQUEUE)
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* Use the low priority work queue if possible */
|
||||
/* Use the low priority work queue if possible */
|
||||
|
||||
#if defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# if defined(CONFIG_C5471_HPWORK)
|
||||
# define ETHWORK HPWORK
|
||||
# elif defined(CONFIG_C5471_LPWORK)
|
||||
@@ -317,9 +312,7 @@ struct c5471_driver_s
|
||||
bool c_bifup; /* true:ifup false:ifdown */
|
||||
WDOG_ID c_txpoll; /* TX poll timer */
|
||||
WDOG_ID c_txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s c_work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
|
||||
/* Note: According to the C547x documentation: "The software has to maintain
|
||||
* two pointers to the current RX-CPU and TX-CPU descriptors. At init time,
|
||||
@@ -407,25 +400,15 @@ static void c5471_txstatus(struct c5471_driver_s *priv);
|
||||
#endif
|
||||
static void c5471_txdone(struct c5471_driver_s *priv);
|
||||
|
||||
static inline void c5471_interrupt_process(FAR struct c5471_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void c5471_interrupt_work(FAR void *arg);
|
||||
#endif
|
||||
|
||||
static int c5471_interrupt(int irq, FAR void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void c5471_txtimeout_process(FAR struct c5471_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void c5471_txtimeout_work(FAR void *arg);
|
||||
#endif
|
||||
static void c5471_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
static inline void c5471_poll_process(FAR struct c5471_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void c5471_poll_work(FAR void *arg);
|
||||
#endif
|
||||
static void c5471_poll_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
@@ -433,10 +416,7 @@ static void c5471_poll_expiry(int argc, uint32_t arg, ...);
|
||||
static int c5471_ifup(struct net_driver_s *dev);
|
||||
static int c5471_ifdown(struct net_driver_s *dev);
|
||||
|
||||
static inline void c5471_txavail_process(FAR struct c5471_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void c5471_txavail_work(FAR void *arg);
|
||||
#endif
|
||||
static int c5471_txavail(struct net_driver_s *dev);
|
||||
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
@@ -1558,25 +1538,30 @@ static void c5471_txdone(struct c5471_driver_s *priv)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: c5471_interrupt_process
|
||||
* Function: c5471_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* The network is locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void c5471_interrupt_process(FAR struct c5471_driver_s *priv)
|
||||
static void c5471_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct c5471_driver_s *priv = (FAR struct c5471_driver_s *)arg;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
net_lock();
|
||||
|
||||
/* Get and clear interrupt status bits */
|
||||
|
||||
priv->c_eimstatus = getreg32(EIM_STATUS);
|
||||
@@ -1624,42 +1609,13 @@ static inline void c5471_interrupt_process(FAR struct c5471_driver_s *priv)
|
||||
|
||||
c5471_txdone(priv);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: c5471_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* The network is locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void c5471_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct c5471_driver_s *priv = (FAR struct c5471_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
c5471_interrupt_process(priv);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts */
|
||||
|
||||
up_enable_irq(C5471_IRQ_ETHER);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: c5471_interrupt
|
||||
@@ -1686,7 +1642,6 @@ static int c5471_interrupt(int irq, FAR void *context)
|
||||
# error "Additional logic needed to support multiple interfaces"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. Because Ethernet interrupts are
|
||||
* also disabled if the TX timeout event occurs, there can be no race
|
||||
* condition here.
|
||||
@@ -1712,52 +1667,9 @@ static int c5471_interrupt(int irq, FAR void *context)
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->c_work, c5471_interrupt_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
c5471_interrupt_process(priv);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: c5471_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void c5471_txtimeout_process(FAR struct c5471_driver_s *priv)
|
||||
{
|
||||
/* Increment statistics */
|
||||
|
||||
#ifdef CONFIG_C5471_NET_STATS
|
||||
priv->c_txtimeouts++;
|
||||
ninfo("c_txtimeouts: %d\n", priv->c_txtimeouts);
|
||||
#endif
|
||||
|
||||
/* Then try to restart the hardware */
|
||||
|
||||
c5471_ifdown(&priv->c_dev);
|
||||
c5471_ifup(&priv->c_dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
(void)devif_poll(&priv->c_dev, c5471_txpoll);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: c5471_txtimeout_work
|
||||
*
|
||||
@@ -1775,20 +1687,29 @@ static inline void c5471_txtimeout_process(FAR struct c5471_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void c5471_txtimeout_work(FAR void *arg)
|
||||
{
|
||||
FAR struct c5471_driver_s *priv = (FAR struct c5471_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
/* Increment statistics */
|
||||
|
||||
state = net_lock();
|
||||
c5471_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
}
|
||||
net_lock();
|
||||
#ifdef CONFIG_C5471_NET_STATS
|
||||
priv->c_txtimeouts++;
|
||||
ninfo("c_txtimeouts: %d\n", priv->c_txtimeouts);
|
||||
#endif
|
||||
|
||||
/* Then try to restart the hardware */
|
||||
|
||||
c5471_ifdown(&priv->c_dev);
|
||||
c5471_ifup(&priv->c_dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
(void)devif_poll(&priv->c_dev, c5471_txpoll);
|
||||
net_unlock();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: c5471_txtimeout_expiry
|
||||
*
|
||||
@@ -1812,7 +1733,6 @@ static void c5471_txtimeout_expiry(int argc, wdparm_t arg, ...)
|
||||
{
|
||||
struct c5471_driver_s *priv = (struct c5471_driver_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -1829,47 +1749,6 @@ static void c5471_txtimeout_expiry(int argc, wdparm_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->c_work, c5471_txtimeout_work, priv, 0);
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
c5471_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: c5471_poll_process
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void c5471_poll_process(FAR struct c5471_driver_s *priv)
|
||||
{
|
||||
/* Check if the ESM has let go of the RX descriptor giving us access rights
|
||||
* to submit another Ethernet frame.
|
||||
*/
|
||||
|
||||
if ((EIM_TXDESC_OWN_HOST & getreg32(priv->c_rxcpudesc)) == 0)
|
||||
{
|
||||
/* If so, update TCP timing states and poll the network for new XMIT data */
|
||||
|
||||
(void)devif_timer(&priv->c_dev, c5471_txpoll);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->c_txpoll, C5471_WDDELAY, c5471_poll_expiry, 1,
|
||||
(wdparm_t)priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -1889,19 +1768,28 @@ static inline void c5471_poll_process(FAR struct c5471_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void c5471_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct c5471_driver_s *priv = (FAR struct c5471_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Check if the ESM has let go of the RX descriptor giving us access rights
|
||||
* to submit another Ethernet frame.
|
||||
*/
|
||||
|
||||
state = net_lock();
|
||||
c5471_poll_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
if ((EIM_TXDESC_OWN_HOST & getreg32(priv->c_rxcpudesc)) == 0)
|
||||
{
|
||||
/* If so, update TCP timing states and poll the network for new XMIT data */
|
||||
|
||||
(void)devif_timer(&priv->c_dev, c5471_txpoll);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->c_txpoll, C5471_WDDELAY, c5471_poll_expiry, 1,
|
||||
(wdparm_t)priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: c5471_poll_expiry
|
||||
@@ -1925,7 +1813,6 @@ static void c5471_poll_expiry(int argc, wdparm_t arg, ...)
|
||||
{
|
||||
struct c5471_driver_s *priv = (struct c5471_driver_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -1945,12 +1832,6 @@ static void c5471_poll_expiry(int argc, wdparm_t arg, ...)
|
||||
(void)wd_start(priv->c_txpoll, C5471_WDDELAY, c5471_poll_expiry,
|
||||
1, arg);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
c5471_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2071,44 +1952,6 @@ static int c5471_ifdown(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: c5471_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void c5471_txavail_process(FAR struct c5471_driver_s *priv)
|
||||
{
|
||||
ninfo("Polling\n");
|
||||
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
if (priv->c_bifup)
|
||||
{
|
||||
/* Check if the ESM has let go of the RX descriptor giving us access
|
||||
* rights to submit another Ethernet frame.
|
||||
*/
|
||||
|
||||
if ((EIM_TXDESC_OWN_HOST & getreg32(priv->c_rxcpudesc)) == 0)
|
||||
{
|
||||
/* If so, then poll the network for new XMIT data */
|
||||
|
||||
(void)devif_poll(&priv->c_dev, c5471_txpoll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: c5471_txavail_work
|
||||
*
|
||||
@@ -2126,19 +1969,31 @@ static inline void c5471_txavail_process(FAR struct c5471_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void c5471_txavail_work(FAR void *arg)
|
||||
{
|
||||
FAR struct c5471_driver_s *priv = (FAR struct c5471_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
ninfo("Polling\n");
|
||||
|
||||
state = net_lock();
|
||||
c5471_txavail_process(priv);
|
||||
net_unlock(state);
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
net_lock();
|
||||
if (priv->c_bifup)
|
||||
{
|
||||
/* Check if the ESM has let go of the RX descriptor giving us access
|
||||
* rights to submit another Ethernet frame.
|
||||
*/
|
||||
|
||||
if ((EIM_TXDESC_OWN_HOST & getreg32(priv->c_rxcpudesc)) == 0)
|
||||
{
|
||||
/* If so, then poll the network for new XMIT data */
|
||||
|
||||
(void)devif_poll(&priv->c_dev, c5471_txpoll);
|
||||
}
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: c5471_txavail
|
||||
@@ -2163,7 +2018,6 @@ static int c5471_txavail(FAR struct net_driver_s *dev)
|
||||
{
|
||||
struct c5471_driver_s *priv = (struct c5471_driver_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -2176,21 +2030,6 @@ static int c5471_txavail(FAR struct net_driver_s *dev)
|
||||
work_queue(ETHWORK, &priv->c_work, c5471_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
irqstate_t flags;
|
||||
|
||||
/* Disable interrupts because this function may be called from interrupt
|
||||
* level processing.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
c5471_txavail_process(priv);
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,14 +53,11 @@
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/mii.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_PKT
|
||||
# include <nuttx/net/pkt.h>
|
||||
#endif
|
||||
@@ -84,13 +81,12 @@
|
||||
* is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# error Work queue support is required
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* Select work queue */
|
||||
/* Select work queue */
|
||||
|
||||
#if defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# if defined(CONFIG_KINETIS_EMAC_HPWORK)
|
||||
# define ETHWORK HPWORK
|
||||
# elif defined(CONFIG_KINETIS_EMAC_LPWORK)
|
||||
@@ -219,9 +215,7 @@ struct kinetis_driver_s
|
||||
uint8_t phyaddr; /* Selected PHY address */
|
||||
WDOG_ID txpoll; /* TX poll timer */
|
||||
WDOG_ID txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
struct enet_desc_s *txdesc; /* A pointer to the list of TX descriptor */
|
||||
struct enet_desc_s *rxdesc; /* A pointer to the list of RX descriptors */
|
||||
|
||||
@@ -279,24 +273,15 @@ static int kinetis_txpoll(struct net_driver_s *dev);
|
||||
static void kinetis_receive(FAR struct kinetis_driver_s *priv);
|
||||
static void kinetis_txdone(FAR struct kinetis_driver_s *priv);
|
||||
|
||||
static inline void kinetis_interrupt_process(FAR struct kinetis_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void kinetis_interrupt_work(FAR void *arg);
|
||||
#endif
|
||||
static int kinetis_interrupt(int irq, FAR void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void kinetis_txtimeout_process(FAR struct kinetis_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void kinetis_txtimeout_work(FAR void *arg);
|
||||
#endif
|
||||
static void kinetis_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
static inline void kinetis_poll_process(FAR struct kinetis_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void kinetis_poll_work(FAR void *arg);
|
||||
#endif
|
||||
static void kinetis_polltimer_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
@@ -304,10 +289,7 @@ static void kinetis_polltimer_expiry(int argc, uint32_t arg, ...);
|
||||
static int kinetis_ifup(struct net_driver_s *dev);
|
||||
static int kinetis_ifdown(struct net_driver_s *dev);
|
||||
|
||||
static inline void kinetis_txavail_process(FAR struct kinetis_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void kinetis_txavail_work(FAR void *arg);
|
||||
#endif
|
||||
static int kinetis_txavail(struct net_driver_s *dev);
|
||||
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
@@ -824,27 +806,31 @@ static void kinetis_txdone(FAR struct kinetis_driver_s *priv)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_interrupt_process
|
||||
* Function: kinetis_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* The network is locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void kinetis_interrupt_process(FAR struct kinetis_driver_s *priv)
|
||||
static void kinetis_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||
uint32_t pending;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
net_lock();
|
||||
|
||||
/* Get the set of unmasked, pending interrupt. */
|
||||
|
||||
pending = getreg32(KINETIS_ENET_EIR) & getreg32(KINETIS_ENET_EIMR);
|
||||
@@ -892,36 +878,8 @@ static inline void kinetis_interrupt_process(FAR struct kinetis_driver_s *priv)
|
||||
|
||||
putreg32(ENET_RDAR, KINETIS_ENET_RDAR);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* The network is locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void kinetis_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
kinetis_interrupt_process(priv);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts */
|
||||
|
||||
@@ -932,7 +890,6 @@ static void kinetis_interrupt_work(FAR void *arg)
|
||||
up_enable_irq(KINETIS_IRQ_EMACRX);
|
||||
up_enable_irq(KINETIS_IRQ_EMACMISC);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_interrupt
|
||||
@@ -958,7 +915,6 @@ static int kinetis_interrupt(int irq, FAR void *context)
|
||||
{
|
||||
register FAR struct kinetis_driver_s *priv = &g_enet[0];
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. Because Ethernet interrupts are
|
||||
* also disabled if the TX timeout event occurs, there can be no race
|
||||
* condition here.
|
||||
@@ -987,51 +943,9 @@ static int kinetis_interrupt(int irq, FAR void *context)
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, kinetis_interrupt_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
kinetis_interrupt_process(priv);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void kinetis_txtimeout_process(FAR struct kinetis_driver_s *priv)
|
||||
{
|
||||
/* Increment statistics and dump debug info */
|
||||
|
||||
NETDEV_TXTIMEOUTS(&priv->dev);
|
||||
|
||||
/* Take the interface down and bring it back up. The is the most agressive
|
||||
* hardware reset.
|
||||
*/
|
||||
|
||||
(void)kinetis_ifdown(&priv->dev);
|
||||
(void)kinetis_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
(void)devif_poll(&priv->dev, kinetis_txpoll);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_txtimeout_work
|
||||
*
|
||||
@@ -1049,19 +963,27 @@ static inline void kinetis_txtimeout_process(FAR struct kinetis_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void kinetis_txtimeout_work(FAR void *arg)
|
||||
{
|
||||
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
/* Increment statistics and dump debug info */
|
||||
|
||||
state = net_lock();
|
||||
kinetis_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
NETDEV_TXTIMEOUTS(&priv->dev);
|
||||
|
||||
/* Take the interface down and bring it back up. The is the most agressive
|
||||
* hardware reset.
|
||||
*/
|
||||
|
||||
(void)kinetis_ifdown(&priv->dev);
|
||||
(void)kinetis_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
(void)devif_poll(&priv->dev, kinetis_txpoll);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_txtimeout_expiry
|
||||
@@ -1086,7 +1008,6 @@ static void kinetis_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -1106,50 +1027,6 @@ static void kinetis_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, kinetis_txtimeout_work, priv, 0);
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
kinetis_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_poll_process
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void kinetis_poll_process(FAR struct kinetis_driver_s *priv)
|
||||
{
|
||||
/* Check if there is there is a transmission in progress. We cannot perform
|
||||
* the TX poll if he are unable to accept another packet for transmission.
|
||||
*/
|
||||
|
||||
if (!kinetics_txringfull(priv))
|
||||
{
|
||||
/* If so, update TCP timing states and poll the network for new XMIT data. Hmmm..
|
||||
* might be bug here. Does this mean if there is a transmit in progress,
|
||||
* we will missing TCP time state updates?
|
||||
*/
|
||||
|
||||
(void)devif_timer(&priv->dev, kinetis_txpoll);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again in any case */
|
||||
|
||||
(void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer_expiry,
|
||||
1, (wdparm_t)priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -1169,19 +1046,31 @@ static inline void kinetis_poll_process(FAR struct kinetis_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void kinetis_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Check if there is there is a transmission in progress. We cannot perform
|
||||
* the TX poll if he are unable to accept another packet for transmission.
|
||||
*/
|
||||
|
||||
state = net_lock();
|
||||
kinetis_poll_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
if (!kinetics_txringfull(priv))
|
||||
{
|
||||
/* If so, update TCP timing states and poll the network for new XMIT data. Hmmm..
|
||||
* might be bug here. Does this mean if there is a transmit in progress,
|
||||
* we will missing TCP time state updates?
|
||||
*/
|
||||
|
||||
(void)devif_timer(&priv->dev, kinetis_txpoll);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again in any case */
|
||||
|
||||
(void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer_expiry,
|
||||
1, (wdparm_t)priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_polltimer_expiry
|
||||
@@ -1205,7 +1094,6 @@ static void kinetis_polltimer_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -1225,12 +1113,6 @@ static void kinetis_polltimer_expiry(int argc, uint32_t arg, ...)
|
||||
(void)wd_start(priv->txpoll, KINETIS_WDDELAY, kinetis_polltimer_expiry,
|
||||
1, (wdparm_t)arg);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
kinetis_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -1416,49 +1298,6 @@ static int kinetis_ifdown(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void kinetis_txavail_process(FAR struct kinetis_driver_s *priv)
|
||||
{
|
||||
net_lock_t state;
|
||||
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
state = net_lock();
|
||||
if (priv->bifup)
|
||||
{
|
||||
/* Check if there is room in the hardware to hold another outgoing
|
||||
* packet.
|
||||
*/
|
||||
|
||||
if (!kinetics_txringfull(priv))
|
||||
{
|
||||
/* No, there is space for another transfer. Poll the network for new
|
||||
* XMIT data.
|
||||
*/
|
||||
|
||||
(void)devif_poll(&priv->dev, kinetis_txpoll);
|
||||
}
|
||||
}
|
||||
|
||||
net_unlock(state);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_txavail_work
|
||||
*
|
||||
@@ -1476,16 +1315,31 @@ static inline void kinetis_txavail_process(FAR struct kinetis_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void kinetis_txavail_work(FAR void *arg)
|
||||
{
|
||||
FAR struct kinetis_driver_s *priv = (FAR struct kinetis_driver_s *)arg;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
kinetis_txavail_process(priv);
|
||||
net_lock();
|
||||
if (priv->bifup)
|
||||
{
|
||||
/* Check if there is room in the hardware to hold another outgoing
|
||||
* packet.
|
||||
*/
|
||||
|
||||
if (!kinetics_txringfull(priv))
|
||||
{
|
||||
/* No, there is space for another transfer. Poll the network for new
|
||||
* XMIT data.
|
||||
*/
|
||||
|
||||
(void)devif_poll(&priv->dev, kinetis_txpoll);
|
||||
}
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: kinetis_txavail
|
||||
@@ -1511,7 +1365,6 @@ static int kinetis_txavail(struct net_driver_s *dev)
|
||||
FAR struct kinetis_driver_s *priv =
|
||||
(FAR struct kinetis_driver_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -1524,12 +1377,6 @@ static int kinetis_txavail(struct net_driver_s *dev)
|
||||
work_queue(ETHWORK, &priv->work, kinetis_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
kinetis_txavail_process(priv);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -53,11 +53,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/wdog.h>
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/mii.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
@@ -87,13 +83,12 @@
|
||||
* is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# error Work queue support is required
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* Select work queue */
|
||||
/* Select work queue */
|
||||
|
||||
#if defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# if defined(CONFIG_LPC43_ETHERNET_HPWORK)
|
||||
# define ETHWORK HPWORK
|
||||
# elif defined(CONFIG_LPC43_ETHERNET_LPWORK)
|
||||
@@ -524,9 +519,7 @@ struct lpc43_ethmac_s
|
||||
uint8_t fduplex : 1; /* Full (vs. half) duplex */
|
||||
WDOG_ID txpoll; /* TX poll timer */
|
||||
WDOG_ID txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
|
||||
/* This holds the information visible to the NuttX network */
|
||||
|
||||
@@ -599,34 +592,26 @@ static int lpc43_recvframe(FAR struct lpc43_ethmac_s *priv);
|
||||
static void lpc43_receive(FAR struct lpc43_ethmac_s *priv);
|
||||
static void lpc43_freeframe(FAR struct lpc43_ethmac_s *priv);
|
||||
static void lpc43_txdone(FAR struct lpc43_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void lpc43_interrupt_work(FAR void *arg);
|
||||
#endif
|
||||
static int lpc43_interrupt(int irq, FAR void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void lpc43_txtimeout_process(FAR struct lpc43_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void lpc43_txtimeout_work(FAR void *arg);
|
||||
#endif
|
||||
static void lpc43_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
static inline void lpc43_poll_process(FAR struct lpc43_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void lpc43_poll_work(FAR void *arg);
|
||||
#endif
|
||||
static void lpc43_poll_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
|
||||
static int lpc43_ifup(struct net_driver_s *dev);
|
||||
static int lpc43_ifdown(struct net_driver_s *dev);
|
||||
static inline void lpc43_txavail_process(FAR struct lpc43_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void lpc43_txavail_work(FAR void *arg);
|
||||
#endif
|
||||
static int lpc43_txavail(struct net_driver_s *dev);
|
||||
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
static int lpc43_addmac(struct net_driver_s *dev, FAR const uint8_t *mac);
|
||||
#endif
|
||||
@@ -1900,29 +1885,32 @@ static void lpc43_txdone(FAR struct lpc43_ethmac_s *priv)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_interrupt_process
|
||||
* Function: lpc43_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void lpc43_interrupt_process(FAR struct lpc43_ethmac_s *priv)
|
||||
static void lpc43_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg;
|
||||
uint32_t dmasr;
|
||||
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
/* Get the DMA interrupt status bits (no MAC interrupts are expected) */
|
||||
|
||||
net_lock();
|
||||
dmasr = lpc43_getreg(LPC43_ETH_DMASTAT);
|
||||
|
||||
/* Mask only enabled interrupts. This depends on the fact that the interrupt
|
||||
@@ -1974,7 +1962,6 @@ static inline void lpc43_interrupt_process(FAR struct lpc43_ethmac_s *priv)
|
||||
/* Handle error interrupt only if CONFIG_DEBUG_NET is eanbled */
|
||||
|
||||
#ifdef CONFIG_DEBUG_NET
|
||||
|
||||
/* Check if there are pending "abnormal" interrupts */
|
||||
|
||||
if ((dmasr & ETH_DMAINT_AIS) != 0)
|
||||
@@ -1991,45 +1978,13 @@ static inline void lpc43_interrupt_process(FAR struct lpc43_ethmac_s *priv)
|
||||
|
||||
lpc43_putreg(ETH_DMAINT_AIS, LPC43_ETH_DMASTAT);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void lpc43_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
lpc43_interrupt_process(priv);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts at the NVIC */
|
||||
|
||||
up_enable_irq(LPC43M4_IRQ_ETHERNET);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_interrupt
|
||||
@@ -2051,8 +2006,6 @@ static void lpc43_interrupt_work(FAR void *arg)
|
||||
static int lpc43_interrupt(int irq, FAR void *context)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = &g_lpc43ethmac;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
uint32_t dmasr;
|
||||
|
||||
/* Get the DMA interrupt status bits (no MAC interrupts are expected) */
|
||||
@@ -2088,49 +2041,9 @@ static int lpc43_interrupt(int irq, FAR void *context)
|
||||
work_queue(ETHWORK, &priv->work, lpc43_interrupt_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
lpc43_interrupt_process(priv);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Global interrupts are disabled by the watchdog logic.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void lpc43_txtimeout_process(FAR struct lpc43_ethmac_s *priv)
|
||||
{
|
||||
/* Then reset the hardware. Just take the interface down, then back
|
||||
* up again.
|
||||
*/
|
||||
|
||||
lpc43_ifdown(&priv->dev);
|
||||
lpc43_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
lpc43_dopoll(priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_txtimeout_work
|
||||
*
|
||||
@@ -2148,19 +2061,23 @@ static inline void lpc43_txtimeout_process(FAR struct lpc43_ethmac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void lpc43_txtimeout_work(FAR void *arg)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
/* Then reset the hardware. Just take the interface down, then back
|
||||
* up again.
|
||||
*/
|
||||
|
||||
state = net_lock();
|
||||
lpc43_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
lpc43_ifdown(&priv->dev);
|
||||
lpc43_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
lpc43_dopoll(priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_txtimeout_expiry
|
||||
@@ -2187,7 +2104,6 @@ static void lpc43_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
|
||||
ninfo("Timeout!\n");
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -2206,33 +2122,28 @@ static void lpc43_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, lpc43_txtimeout_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
lpc43_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_poll_process
|
||||
* Function: lpc43_poll_work
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
* Perform periodic polling from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() as called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void lpc43_poll_process(FAR struct lpc43_ethmac_s *priv)
|
||||
static void lpc43_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg;
|
||||
FAR struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
/* Check if the next TX descriptor is owned by the Ethernet DMA or CPU. We
|
||||
@@ -2246,6 +2157,7 @@ static inline void lpc43_poll_process(FAR struct lpc43_ethmac_s *priv)
|
||||
* CONFIG_LPC43_ETH_NTXDESC).
|
||||
*/
|
||||
|
||||
net_lock();
|
||||
if ((priv->txhead->tdes0 & ETH_TDES0_OWN) == 0 &&
|
||||
priv->txhead->tdes2 == 0)
|
||||
{
|
||||
@@ -2281,39 +2193,9 @@ static inline void lpc43_poll_process(FAR struct lpc43_ethmac_s *priv)
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->txpoll, LPC43_WDDELAY, lpc43_poll_expiry, 1, priv);
|
||||
net_unlock();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_poll_work
|
||||
*
|
||||
* Description:
|
||||
* Perform periodic polling from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() as called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void lpc43_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
|
||||
state = net_lock();
|
||||
lpc43_poll_process(priv);
|
||||
net_unlock(state);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_poll_expiry
|
||||
*
|
||||
@@ -2336,7 +2218,6 @@ static void lpc43_poll_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -2356,12 +2237,6 @@ static void lpc43_poll_expiry(int argc, uint32_t arg, ...)
|
||||
(void)wd_start(priv->txpoll, LPC43_WDDELAY, lpc43_poll_expiry, 1,
|
||||
(uint32_t)priv);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
lpc43_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2467,37 +2342,6 @@ static int lpc43_ifdown(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void lpc43_txavail_process(FAR struct lpc43_ethmac_s *priv)
|
||||
{
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll for new XMIT data */
|
||||
|
||||
lpc43_dopoll(priv);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_txavail_work
|
||||
*
|
||||
@@ -2515,19 +2359,23 @@ static inline void lpc43_txavail_process(FAR struct lpc43_ethmac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void lpc43_txavail_work(FAR void *arg)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
state = net_lock();
|
||||
lpc43_txavail_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll for new XMIT data */
|
||||
|
||||
lpc43_dopoll(priv);
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: lpc43_txavail
|
||||
@@ -2552,7 +2400,6 @@ static int lpc43_txavail(struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct lpc43_ethmac_s *priv = (FAR struct lpc43_ethmac_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -2565,21 +2412,6 @@ static int lpc43_txavail(struct net_driver_s *dev)
|
||||
work_queue(ETHWORK, &priv->work, lpc43_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
irqstate_t flags;
|
||||
|
||||
/* Disable interrupts because this function may be called from interrupt
|
||||
* level processing.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
lpc43_txavail_process(priv);
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
+57
-221
@@ -64,11 +64,7 @@
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/mii.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
@@ -101,13 +97,12 @@
|
||||
* is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# error Work queue support is required
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* Select work queue */
|
||||
/* Select work queue */
|
||||
|
||||
#if defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# if defined(CONFIG_SAM34_EMAC_HPWORK)
|
||||
# define ETHWORK HPWORK
|
||||
# elif defined(CONFIG_SAM34_EMAC_LPWORK)
|
||||
@@ -275,9 +270,7 @@ struct sam_emac_s
|
||||
uint8_t ifup : 1; /* true:ifup false:ifdown */
|
||||
WDOG_ID txpoll; /* TX poll timer */
|
||||
WDOG_ID txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
|
||||
/* This holds the information visible to the NuttX network */
|
||||
|
||||
@@ -386,24 +379,16 @@ static void sam_dopoll(struct sam_emac_s *priv);
|
||||
static int sam_recvframe(struct sam_emac_s *priv);
|
||||
static void sam_receive(struct sam_emac_s *priv);
|
||||
static void sam_txdone(struct sam_emac_s *priv);
|
||||
static inline void sam_interrupt_process(FAR struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void sam_interrupt_work(FAR void *arg);
|
||||
#endif
|
||||
static int sam_emac_interrupt(int irq, void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txtimeout_work(FAR void *arg);
|
||||
#endif
|
||||
static void sam_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
static inline void sam_poll_process(FAR struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_poll_work(FAR void *arg);
|
||||
#endif
|
||||
static void sam_poll_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
@@ -411,10 +396,7 @@ static void sam_poll_expiry(int argc, uint32_t arg, ...);
|
||||
static int sam_ifup(struct net_driver_s *dev);
|
||||
static int sam_ifdown(struct net_driver_s *dev);
|
||||
|
||||
static inline void sam_txavail_process(FAR struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txavail_work(FAR void *arg);
|
||||
#endif
|
||||
static int sam_txavail(struct net_driver_s *dev);
|
||||
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
@@ -465,6 +447,7 @@ static int sam_emac_configure(struct sam_emac_s *priv);
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_checkreg
|
||||
*
|
||||
@@ -1421,25 +1404,25 @@ static void sam_txdone(struct sam_emac_s *priv)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_interrupt_process
|
||||
* Function: sam_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_interrupt_process(FAR struct sam_emac_s *priv)
|
||||
static void sam_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
uint32_t isr;
|
||||
uint32_t rsr;
|
||||
uint32_t tsr;
|
||||
@@ -1448,6 +1431,9 @@ static inline void sam_interrupt_process(FAR struct sam_emac_s *priv)
|
||||
uint32_t pending;
|
||||
uint32_t clrbits;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
net_lock();
|
||||
isr = sam_getreg(priv, SAM_EMAC_ISR);
|
||||
rsr = sam_getreg(priv, SAM_EMAC_RSR);
|
||||
tsr = sam_getreg(priv, SAM_EMAC_TSR);
|
||||
@@ -1603,42 +1589,13 @@ static inline void sam_interrupt_process(FAR struct sam_emac_s *priv)
|
||||
nwarn("WARNING: Pause TO!\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
sam_interrupt_process(priv);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts */
|
||||
|
||||
up_enable_irq(SAM_IRQ_EMAC);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_emac_interrupt
|
||||
@@ -1661,7 +1618,6 @@ static int sam_emac_interrupt(int irq, void *context)
|
||||
{
|
||||
struct sam_emac_s *priv = &g_emac;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
uint32_t tsr;
|
||||
|
||||
/* Disable further Ethernet interrupts. Because Ethernet interrupts are
|
||||
@@ -1705,52 +1661,9 @@ static int sam_emac_interrupt(int irq, void *context)
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, sam_interrupt_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
sam_interrupt_process(priv);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Global interrupts are disabled by the watchdog logic.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv)
|
||||
{
|
||||
nerr("ERROR: Timeout!\n");
|
||||
|
||||
/* Then reset the hardware. Just take the interface down, then back
|
||||
* up again.
|
||||
*/
|
||||
|
||||
sam_ifdown(&priv->dev);
|
||||
sam_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txtimeout_work
|
||||
*
|
||||
@@ -1768,19 +1681,25 @@ static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txtimeout_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
nerr("ERROR: Timeout!\n");
|
||||
|
||||
state = net_lock();
|
||||
sam_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
/* Then reset the hardware. Just take the interface down, then back
|
||||
* up again.
|
||||
*/
|
||||
|
||||
net_lock();
|
||||
sam_ifdown(&priv->dev);
|
||||
sam_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txtimeout_expiry
|
||||
@@ -1805,7 +1724,6 @@ static void sam_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -1822,48 +1740,6 @@ static void sam_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, sam_txtimeout_work, priv, 0);
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
sam_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_poll_process
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_poll_process(FAR struct sam_emac_s *priv)
|
||||
{
|
||||
struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
/* Check if the there are any free TX descriptors. We cannot perform the
|
||||
* TX poll if we do not have buffering for another packet.
|
||||
*/
|
||||
|
||||
if (sam_txfree(priv) > 0)
|
||||
{
|
||||
/* Update TCP timing states and poll the network for new XMIT data. */
|
||||
|
||||
(void)devif_timer(dev, sam_txpoll);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -1883,19 +1759,28 @@ static inline void sam_poll_process(FAR struct sam_emac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
net_lock_t state;
|
||||
struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Check if the there are any free TX descriptors. We cannot perform the
|
||||
* TX poll if we do not have buffering for another packet.
|
||||
*/
|
||||
|
||||
state = net_lock();
|
||||
sam_poll_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
if (sam_txfree(priv) > 0)
|
||||
{
|
||||
/* Update TCP timing states and poll the network for new XMIT data. */
|
||||
|
||||
(void)devif_timer(dev, sam_txpoll);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_poll_expiry
|
||||
@@ -1919,7 +1804,6 @@ static void sam_poll_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -1938,12 +1822,6 @@ static void sam_poll_expiry(int argc, uint32_t arg, ...)
|
||||
|
||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, arg);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
sam_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2070,37 +1948,6 @@ static int sam_ifdown(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_txavail_process(FAR struct sam_emac_s *priv)
|
||||
{
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txavail_work
|
||||
*
|
||||
@@ -2118,19 +1965,24 @@ static inline void sam_txavail_process(FAR struct sam_emac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txavail_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
state = net_lock();
|
||||
sam_txavail_process(priv);
|
||||
net_unlock(state);
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
net_lock();
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv);
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txavail
|
||||
@@ -2155,7 +2007,6 @@ static int sam_txavail(struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -2168,21 +2019,6 @@ static int sam_txavail(struct net_driver_s *dev)
|
||||
work_queue(ETHWORK, &priv->work, sam_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
irqstate_t flags;
|
||||
|
||||
/* Disable interrupts because this function may be called from interrupt
|
||||
* level processing.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
sam_txavail_process(priv);
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
+54
-219
@@ -65,11 +65,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/mii.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
@@ -103,13 +99,12 @@
|
||||
* is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# error Work queue support is required
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* Select work queue */
|
||||
/* Select work queue */
|
||||
|
||||
#if defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# if defined(CONFIG_SAMA5_EMACA_HPWORK)
|
||||
# define ETHWORK HPWORK
|
||||
# elif defined(CONFIG_SAMA5_EMACA_LPWORK)
|
||||
@@ -280,9 +275,7 @@ struct sam_emac_s
|
||||
uint8_t ifup : 1; /* true:ifup false:ifdown */
|
||||
WDOG_ID txpoll; /* TX poll timer */
|
||||
WDOG_ID txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
|
||||
/* This holds the information visible to the NuttX network */
|
||||
|
||||
@@ -391,24 +384,16 @@ static void sam_dopoll(struct sam_emac_s *priv);
|
||||
static int sam_recvframe(struct sam_emac_s *priv);
|
||||
static void sam_receive(struct sam_emac_s *priv);
|
||||
static void sam_txdone(struct sam_emac_s *priv);
|
||||
static inline void sam_interrupt_process(FAR struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void sam_interrupt_work(FAR void *arg);
|
||||
#endif
|
||||
static int sam_emac_interrupt(int irq, void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txtimeout_work(FAR void *arg);
|
||||
#endif
|
||||
static void sam_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
static inline void sam_poll_process(FAR struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_poll_work(FAR void *arg);
|
||||
#endif
|
||||
static void sam_poll_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
@@ -416,10 +401,7 @@ static void sam_poll_expiry(int argc, uint32_t arg, ...);
|
||||
static int sam_ifup(struct net_driver_s *dev);
|
||||
static int sam_ifdown(struct net_driver_s *dev);
|
||||
|
||||
static inline void sam_txavail_process(FAR struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txavail_work(FAR void *arg);
|
||||
#endif
|
||||
static int sam_txavail(struct net_driver_s *dev);
|
||||
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
@@ -1462,25 +1444,25 @@ static void sam_txdone(struct sam_emac_s *priv)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_interrupt_process
|
||||
* Function: sam_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_interrupt_process(FAR struct sam_emac_s *priv)
|
||||
static void sam_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
uint32_t isr;
|
||||
uint32_t rsr;
|
||||
uint32_t tsr;
|
||||
@@ -1489,6 +1471,9 @@ static inline void sam_interrupt_process(FAR struct sam_emac_s *priv)
|
||||
uint32_t pending;
|
||||
uint32_t clrbits;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
net_lock();
|
||||
isr = sam_getreg(priv, SAM_EMAC_ISR);
|
||||
rsr = sam_getreg(priv, SAM_EMAC_RSR);
|
||||
tsr = sam_getreg(priv, SAM_EMAC_TSR);
|
||||
@@ -1643,42 +1628,13 @@ static inline void sam_interrupt_process(FAR struct sam_emac_s *priv)
|
||||
nwarn("WARNING: Pause TO!\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
sam_interrupt_process(priv);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts */
|
||||
|
||||
up_enable_irq(SAM_IRQ_EMAC);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_emac_interrupt
|
||||
@@ -1700,7 +1656,6 @@ static void sam_interrupt_work(FAR void *arg)
|
||||
static int sam_emac_interrupt(int irq, void *context)
|
||||
{
|
||||
struct sam_emac_s *priv = &g_emac;
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
uint32_t tsr;
|
||||
|
||||
/* Disable further Ethernet interrupts. Because Ethernet interrupts are
|
||||
@@ -1744,50 +1699,9 @@ static int sam_emac_interrupt(int irq, void *context)
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, sam_interrupt_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
sam_interrupt_process(priv);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Global interrupts are disabled by the watchdog logic.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv)
|
||||
{
|
||||
nerr("ERROR: Timeout!\n");
|
||||
|
||||
/* Reset the hardware. Just take the interface down, then back up again. */
|
||||
|
||||
sam_ifdown(&priv->dev);
|
||||
sam_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txtimeout_work
|
||||
*
|
||||
@@ -1805,19 +1719,23 @@ static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txtimeout_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
nerr("ERROR: Timeout!\n");
|
||||
|
||||
state = net_lock();
|
||||
sam_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
/* Reset the hardware. Just take the interface down, then back up again. */
|
||||
|
||||
net_lock();
|
||||
sam_ifdown(&priv->dev);
|
||||
sam_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txtimeout_expiry
|
||||
@@ -1842,7 +1760,6 @@ static void sam_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -1859,48 +1776,6 @@ static void sam_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, sam_txtimeout_work, priv, 0);
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
sam_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_poll_process
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_poll_process(FAR struct sam_emac_s *priv)
|
||||
{
|
||||
struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
/* Check if the there are any free TX descriptors. We cannot perform the
|
||||
* TX poll if we do not have buffering for another packet.
|
||||
*/
|
||||
|
||||
if (sam_txfree(priv) > 0)
|
||||
{
|
||||
/* Update TCP timing states and poll the network for new XMIT data. */
|
||||
|
||||
(void)devif_timer(dev, sam_txpoll);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -1920,19 +1795,28 @@ static inline void sam_poll_process(FAR struct sam_emac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
net_lock_t state;
|
||||
struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Check if the there are any free TX descriptors. We cannot perform the
|
||||
* TX poll if we do not have buffering for another packet.
|
||||
*/
|
||||
|
||||
state = net_lock();
|
||||
sam_poll_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
if (sam_txfree(priv) > 0)
|
||||
{
|
||||
/* Update TCP timing states and poll the network for new XMIT data. */
|
||||
|
||||
(void)devif_timer(dev, sam_txpoll);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_poll_expiry
|
||||
@@ -1956,7 +1840,6 @@ static void sam_poll_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -1975,12 +1858,6 @@ static void sam_poll_expiry(int argc, uint32_t arg, ...)
|
||||
|
||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, arg);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
sam_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2107,37 +1984,6 @@ static int sam_ifdown(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_txavail_process(FAR struct sam_emac_s *priv)
|
||||
{
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txavail_work
|
||||
*
|
||||
@@ -2155,19 +2001,24 @@ static inline void sam_txavail_process(FAR struct sam_emac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txavail_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
state = net_lock();
|
||||
sam_txavail_process(priv);
|
||||
net_unlock(state);
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
net_lock();
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv);
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txavail
|
||||
@@ -2192,7 +2043,6 @@ static int sam_txavail(struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -2205,21 +2055,6 @@ static int sam_txavail(struct net_driver_s *dev)
|
||||
work_queue(ETHWORK, &priv->work, sam_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
irqstate_t flags;
|
||||
|
||||
/* Disable interrupts because this function may be called from interrupt
|
||||
* level processing.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
sam_txavail_process(priv);
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
+54
-219
@@ -79,11 +79,7 @@
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/mii.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
@@ -117,13 +113,12 @@
|
||||
* is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# error Work queue support is required
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* Select work queue */
|
||||
/* Select work queue */
|
||||
|
||||
#if defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# if defined(CONFIG_SAMA5_EMACB_HPWORK)
|
||||
# define ETHWORK HPWORK
|
||||
# elif defined(CONFIG_SAMA5_EMACB_LPWORK)
|
||||
@@ -418,9 +413,7 @@ struct sam_emac_s
|
||||
uint8_t ifup : 1; /* true:ifup false:ifdown */
|
||||
WDOG_ID txpoll; /* TX poll timer */
|
||||
WDOG_ID txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
|
||||
/* This holds the information visible to the NuttX network */
|
||||
|
||||
@@ -486,10 +479,8 @@ static void sam_dopoll(struct sam_emac_s *priv);
|
||||
static int sam_recvframe(struct sam_emac_s *priv);
|
||||
static void sam_receive(struct sam_emac_s *priv);
|
||||
static void sam_txdone(struct sam_emac_s *priv);
|
||||
static inline void sam_interrupt_process(FAR struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void sam_interrupt_work(FAR void *arg);
|
||||
#endif
|
||||
static int sam_emac_interrupt(struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_SAMA5_EMAC0
|
||||
static int sam_emac0_interrupt(int irq, void *context);
|
||||
@@ -500,16 +491,10 @@ static int sam_emac1_interrupt(int irq, void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txtimeout_work(FAR void *arg);
|
||||
#endif
|
||||
static void sam_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
static inline void sam_poll_process(FAR struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_poll_work(FAR void *arg);
|
||||
#endif
|
||||
static void sam_poll_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
@@ -517,10 +502,7 @@ static void sam_poll_expiry(int argc, uint32_t arg, ...);
|
||||
static int sam_ifup(struct net_driver_s *dev);
|
||||
static int sam_ifdown(struct net_driver_s *dev);
|
||||
|
||||
static inline void sam_txavail_process(FAR struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txavail_work(FAR void *arg);
|
||||
#endif
|
||||
static int sam_txavail(struct net_driver_s *dev);
|
||||
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
@@ -1830,25 +1812,25 @@ static void sam_txdone(struct sam_emac_s *priv)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_interrupt_process
|
||||
* Function: sam_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_interrupt_process(FAR struct sam_emac_s *priv)
|
||||
static void sam_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
uint32_t isr;
|
||||
uint32_t rsr;
|
||||
uint32_t tsr;
|
||||
@@ -1857,6 +1839,9 @@ static inline void sam_interrupt_process(FAR struct sam_emac_s *priv)
|
||||
uint32_t pending;
|
||||
uint32_t clrbits;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
net_lock();
|
||||
isr = sam_getreg(priv, SAM_EMAC_ISR_OFFSET);
|
||||
rsr = sam_getreg(priv, SAM_EMAC_RSR_OFFSET);
|
||||
tsr = sam_getreg(priv, SAM_EMAC_TSR_OFFSET);
|
||||
@@ -2012,42 +1997,13 @@ static inline void sam_interrupt_process(FAR struct sam_emac_s *priv)
|
||||
nwarn("WARNING: Pause TO!\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
sam_interrupt_process(priv);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts */
|
||||
|
||||
up_enable_irq(priv->attr->irq);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_emac_interrupt
|
||||
@@ -2067,7 +2023,6 @@ static void sam_interrupt_work(FAR void *arg)
|
||||
|
||||
static int sam_emac_interrupt(struct sam_emac_s *priv)
|
||||
{
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
uint32_t tsr;
|
||||
|
||||
/* Disable further Ethernet interrupts. Because Ethernet interrupts are
|
||||
@@ -2111,13 +2066,6 @@ static int sam_emac_interrupt(struct sam_emac_s *priv)
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, sam_interrupt_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
sam_interrupt_process(priv);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -2152,40 +2100,6 @@ static int sam_emac1_interrupt(int irq, void *context)
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Global interrupts are disabled by the watchdog logic.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv)
|
||||
{
|
||||
nerr("ERROR: Timeout!\n");
|
||||
|
||||
/* Reset the hardware. Just take the interface down, then back up again. */
|
||||
|
||||
sam_ifdown(&priv->dev);
|
||||
sam_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txtimeout_work
|
||||
*
|
||||
@@ -2203,19 +2117,23 @@ static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txtimeout_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
nerr("ERROR: Timeout!\n");
|
||||
|
||||
state = net_lock();
|
||||
sam_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
/* Reset the hardware. Just take the interface down, then back up again. */
|
||||
|
||||
net_lock();
|
||||
sam_ifdown(&priv->dev);
|
||||
sam_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txtimeout_expiry
|
||||
@@ -2240,7 +2158,6 @@ static void sam_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -2257,48 +2174,6 @@ static void sam_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, sam_txtimeout_work, priv, 0);
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
sam_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_poll_process
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_poll_process(FAR struct sam_emac_s *priv)
|
||||
{
|
||||
struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
/* Check if the there are any free TX descriptors. We cannot perform the
|
||||
* TX poll if we do not have buffering for another packet.
|
||||
*/
|
||||
|
||||
if (sam_txfree(priv) > 0)
|
||||
{
|
||||
/* Update TCP timing states and poll the network for new XMIT data. */
|
||||
|
||||
(void)devif_timer(dev, sam_txpoll);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2318,19 +2193,28 @@ static inline void sam_poll_process(FAR struct sam_emac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
net_lock_t state;
|
||||
struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Check if the there are any free TX descriptors. We cannot perform the
|
||||
* TX poll if we do not have buffering for another packet.
|
||||
*/
|
||||
|
||||
state = net_lock();
|
||||
sam_poll_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
if (sam_txfree(priv) > 0)
|
||||
{
|
||||
/* Update TCP timing states and poll the network for new XMIT data. */
|
||||
|
||||
(void)devif_timer(dev, sam_txpoll);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_poll_expiry
|
||||
@@ -2354,7 +2238,6 @@ static void sam_poll_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -2373,12 +2256,6 @@ static void sam_poll_expiry(int argc, uint32_t arg, ...)
|
||||
|
||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, arg);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
sam_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2513,37 +2390,6 @@ static int sam_ifdown(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_txavail_process(FAR struct sam_emac_s *priv)
|
||||
{
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txavail_work
|
||||
*
|
||||
@@ -2561,19 +2407,24 @@ static inline void sam_txavail_process(FAR struct sam_emac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txavail_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
state = net_lock();
|
||||
sam_txavail_process(priv);
|
||||
net_unlock(state);
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
net_lock();
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv);
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txavail
|
||||
@@ -2598,7 +2449,6 @@ static int sam_txavail(struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -2611,21 +2461,6 @@ static int sam_txavail(struct net_driver_s *dev)
|
||||
work_queue(ETHWORK, &priv->work, sam_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
irqstate_t flags;
|
||||
|
||||
/* Disable interrupts because this function may be called from interrupt
|
||||
* level processing.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
sam_txavail_process(priv);
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
+54
-219
@@ -62,11 +62,7 @@
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/gmii.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
@@ -100,13 +96,12 @@
|
||||
* is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# error Work queue support is required
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* Select work queue */
|
||||
/* Select work queue */
|
||||
|
||||
#if defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# if defined(CONFIG_SAMA5_GMAC_HPWORK)
|
||||
# define ETHWORK HPWORK
|
||||
# elif defined(CONFIG_SAMA5_GMAC_LPWORK)
|
||||
@@ -206,9 +201,7 @@ struct sam_gmac_s
|
||||
uint8_t ifup : 1; /* true:ifup false:ifdown */
|
||||
WDOG_ID txpoll; /* TX poll timer */
|
||||
WDOG_ID txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
|
||||
/* This holds the information visible to the NuttX network */
|
||||
|
||||
@@ -316,24 +309,16 @@ static void sam_dopoll(struct sam_gmac_s *priv);
|
||||
static int sam_recvframe(struct sam_gmac_s *priv);
|
||||
static void sam_receive(struct sam_gmac_s *priv);
|
||||
static void sam_txdone(struct sam_gmac_s *priv);
|
||||
static inline void sam_interrupt_process(FAR struct sam_gmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void sam_interrupt_work(FAR void *arg);
|
||||
#endif
|
||||
static int sam_gmac_interrupt(int irq, void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void sam_txtimeout_process(FAR struct sam_gmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txtimeout_work(FAR void *arg);
|
||||
#endif
|
||||
static void sam_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
static inline void sam_poll_process(FAR struct sam_gmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_poll_work(FAR void *arg);
|
||||
#endif
|
||||
static void sam_poll_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
@@ -341,10 +326,7 @@ static void sam_poll_expiry(int argc, uint32_t arg, ...);
|
||||
static int sam_ifup(struct net_driver_s *dev);
|
||||
static int sam_ifdown(struct net_driver_s *dev);
|
||||
|
||||
static inline void sam_txavail_process(FAR struct sam_gmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txavail_work(FAR void *arg);
|
||||
#endif
|
||||
static int sam_txavail(struct net_driver_s *dev);
|
||||
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
@@ -1390,25 +1372,25 @@ static void sam_txdone(struct sam_gmac_s *priv)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_interrupt_process
|
||||
* Function: sam_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_interrupt_process(FAR struct sam_gmac_s *priv)
|
||||
static void sam_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_gmac_s *priv = (FAR struct sam_gmac_s *)arg;
|
||||
uint32_t isr;
|
||||
uint32_t rsr;
|
||||
uint32_t tsr;
|
||||
@@ -1417,6 +1399,9 @@ static inline void sam_interrupt_process(FAR struct sam_gmac_s *priv)
|
||||
uint32_t pending;
|
||||
uint32_t clrbits;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
net_lock();
|
||||
isr = sam_getreg(priv, SAM_GMAC_ISR);
|
||||
rsr = sam_getreg(priv, SAM_GMAC_RSR);
|
||||
tsr = sam_getreg(priv, SAM_GMAC_TSR);
|
||||
@@ -1595,42 +1580,13 @@ static inline void sam_interrupt_process(FAR struct sam_gmac_s *priv)
|
||||
nwarn("WARNING: Pause TO!\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_gmac_s *priv = (FAR struct sam_gmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
sam_interrupt_process(priv);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts */
|
||||
|
||||
up_enable_irq(SAM_IRQ_GMAC);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_gmac_interrupt
|
||||
@@ -1652,7 +1608,6 @@ static void sam_interrupt_work(FAR void *arg)
|
||||
static int sam_gmac_interrupt(int irq, void *context)
|
||||
{
|
||||
struct sam_gmac_s *priv = &g_gmac;
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
uint32_t tsr;
|
||||
|
||||
/* Disable further Ethernet interrupts. Because Ethernet interrupts are
|
||||
@@ -1696,50 +1651,9 @@ static int sam_gmac_interrupt(int irq, void *context)
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, sam_interrupt_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
sam_interrupt_process(priv);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Global interrupts are disabled by the watchdog logic.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_txtimeout_process(FAR struct sam_gmac_s *priv)
|
||||
{
|
||||
nerr("ERROR: Timeout!\n");
|
||||
|
||||
/* Reset the hardware. Just take the interface down, then back up again. */
|
||||
|
||||
sam_ifdown(&priv->dev);
|
||||
sam_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txtimeout_work
|
||||
*
|
||||
@@ -1757,19 +1671,23 @@ static inline void sam_txtimeout_process(FAR struct sam_gmac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txtimeout_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_gmac_s *priv = (FAR struct sam_gmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
nerr("ERROR: Timeout!\n");
|
||||
|
||||
state = net_lock();
|
||||
sam_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
/* Reset the hardware. Just take the interface down, then back up again. */
|
||||
|
||||
net_lock();
|
||||
sam_ifdown(&priv->dev);
|
||||
sam_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txtimeout_expiry
|
||||
@@ -1794,7 +1712,6 @@ static void sam_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct sam_gmac_s *priv = (FAR struct sam_gmac_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -1811,48 +1728,6 @@ static void sam_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, sam_txtimeout_work, priv, 0);
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
sam_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_poll_process
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_poll_process(FAR struct sam_gmac_s *priv)
|
||||
{
|
||||
struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
/* Check if the there are any free TX descriptors. We cannot perform the
|
||||
* TX poll if we do not have buffering for another packet.
|
||||
*/
|
||||
|
||||
if (sam_txfree(priv) > 0)
|
||||
{
|
||||
/* Update TCP timing states and poll the network for new XMIT data. */
|
||||
|
||||
(void)devif_timer(dev, sam_txpoll);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -1872,19 +1747,28 @@ static inline void sam_poll_process(FAR struct sam_gmac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_gmac_s *priv = (FAR struct sam_gmac_s *)arg;
|
||||
net_lock_t state;
|
||||
struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Check if the there are any free TX descriptors. We cannot perform the
|
||||
* TX poll if we do not have buffering for another packet.
|
||||
*/
|
||||
|
||||
state = net_lock();
|
||||
sam_poll_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
if (sam_txfree(priv) > 0)
|
||||
{
|
||||
/* Update TCP timing states and poll the network for new XMIT data. */
|
||||
|
||||
(void)devif_timer(dev, sam_txpoll);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_poll_expiry
|
||||
@@ -1908,7 +1792,6 @@ static void sam_poll_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct sam_gmac_s *priv = (FAR struct sam_gmac_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -1927,12 +1810,6 @@ static void sam_poll_expiry(int argc, uint32_t arg, ...)
|
||||
|
||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, arg);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
sam_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2062,37 +1939,6 @@ static int sam_ifdown(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_txavail_process(FAR struct sam_gmac_s *priv)
|
||||
{
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txavail_work
|
||||
*
|
||||
@@ -2110,19 +1956,24 @@ static inline void sam_txavail_process(FAR struct sam_gmac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txavail_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_gmac_s *priv = (FAR struct sam_gmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
state = net_lock();
|
||||
sam_txavail_process(priv);
|
||||
net_unlock(state);
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
net_lock();
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv);
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txavail
|
||||
@@ -2147,7 +1998,6 @@ static int sam_txavail(struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct sam_gmac_s *priv = (FAR struct sam_gmac_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -2160,21 +2010,6 @@ static int sam_txavail(struct net_driver_s *dev)
|
||||
work_queue(ETHWORK, &priv->work, sam_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
irqstate_t flags;
|
||||
|
||||
/* Disable interrupts because this function may be called from interrupt
|
||||
* level processing.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
sam_txavail_process(priv);
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
+57
-222
@@ -69,11 +69,7 @@
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/mii.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
@@ -107,13 +103,12 @@
|
||||
* is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# error Work queue support is required
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* Select work queue */
|
||||
/* Select work queue */
|
||||
|
||||
#if defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# if defined(CONFIG_SAMV7_EMAC_HPWORK)
|
||||
# define ETHWORK HPWORK
|
||||
# elif defined(CONFIG_SAMV7_EMAC_LPWORK)
|
||||
@@ -523,9 +518,7 @@ struct sam_emac_s
|
||||
uint8_t ifup : 1; /* true:ifup false:ifdown */
|
||||
WDOG_ID txpoll; /* TX poll timer */
|
||||
WDOG_ID txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
|
||||
/* This holds the information visible to the NuttX network */
|
||||
|
||||
@@ -588,11 +581,8 @@ static int sam_recvframe(struct sam_emac_s *priv, int qid);
|
||||
static void sam_receive(struct sam_emac_s *priv, int qid);
|
||||
static void sam_txdone(struct sam_emac_s *priv, int qid);
|
||||
static void sam_txerr_interrupt(FAR struct sam_emac_s *priv, int qid);
|
||||
static inline void sam_interrupt_process(FAR struct sam_emac_s *priv,
|
||||
int qid);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void sam_interrupt_work(FAR void *arg);
|
||||
#endif
|
||||
static int sam_emac_interrupt(struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_SAMV7_EMAC0
|
||||
static int sam_emac0_interrupt(int irq, void *context);
|
||||
@@ -603,16 +593,10 @@ static int sam_emac1_interrupt(int irq, void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txtimeout_work(FAR void *arg);
|
||||
#endif
|
||||
static void sam_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
static inline void sam_poll_process(FAR struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_poll_work(FAR void *arg);
|
||||
#endif
|
||||
static void sam_poll_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
@@ -620,10 +604,7 @@ static void sam_poll_expiry(int argc, uint32_t arg, ...);
|
||||
static int sam_ifup(struct net_driver_s *dev);
|
||||
static int sam_ifdown(struct net_driver_s *dev);
|
||||
|
||||
static inline void sam_txavail_process(FAR struct sam_emac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txavail_work(FAR void *arg);
|
||||
#endif
|
||||
static int sam_txavail(struct net_driver_s *dev);
|
||||
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
@@ -2272,26 +2253,25 @@ static void sam_txerr_interrupt(FAR struct sam_emac_s *priv, int qid)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_interrupt_process
|
||||
* Function: sam_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* quid - Index of the transfer queue that generated the interrupt
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_interrupt_process(FAR struct sam_emac_s *priv, int qid)
|
||||
static void sam_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
uint32_t isr;
|
||||
uint32_t rsr;
|
||||
uint32_t tsr;
|
||||
@@ -2300,6 +2280,10 @@ static inline void sam_interrupt_process(FAR struct sam_emac_s *priv, int qid)
|
||||
uint32_t pending;
|
||||
uint32_t clrbits;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
net_lock();
|
||||
|
||||
/* Read the interrupt status, RX status, and TX status registers.
|
||||
* NOTE that the interrupt status register is cleared by this read.
|
||||
*/
|
||||
@@ -2458,42 +2442,13 @@ static inline void sam_interrupt_process(FAR struct sam_emac_s *priv, int qid)
|
||||
ninfo("Pause TO!\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
sam_interrupt_process(priv, EMAC_QUEUE_0);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts */
|
||||
|
||||
up_enable_irq(priv->attr->irq);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_emac_interrupt
|
||||
@@ -2513,7 +2468,6 @@ static void sam_interrupt_work(FAR void *arg)
|
||||
|
||||
static int sam_emac_interrupt(struct sam_emac_s *priv)
|
||||
{
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
uint32_t tsr;
|
||||
|
||||
/* Disable further Ethernet interrupts. Because Ethernet interrupts are
|
||||
@@ -2557,13 +2511,6 @@ static int sam_emac_interrupt(struct sam_emac_s *priv)
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, sam_interrupt_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
sam_interrupt_process(priv, EMAC_QUEUE_0);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -2598,41 +2545,6 @@ static int sam_emac1_interrupt(int irq, void *context)
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Global interrupts are disabled by the watchdog logic.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv)
|
||||
{
|
||||
nerr("ERROR: Timeout!\n");
|
||||
NETDEV_TXTIMEOUTS(&priv->dev);
|
||||
|
||||
/* Reset the hardware. Just take the interface down, then back up again. */
|
||||
|
||||
sam_ifdown(&priv->dev);
|
||||
sam_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv, EMAC_QUEUE_0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txtimeout_work
|
||||
*
|
||||
@@ -2650,19 +2562,25 @@ static inline void sam_txtimeout_process(FAR struct sam_emac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txtimeout_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
nerr("ERROR: Timeout!\n");
|
||||
|
||||
state = net_lock();
|
||||
sam_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
NETDEV_TXTIMEOUTS(&priv->dev);
|
||||
|
||||
/* Reset the hardware. Just take the interface down, then back up again. */
|
||||
|
||||
sam_ifdown(&priv->dev);
|
||||
sam_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv, EMAC_QUEUE_0);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txtimeout_expiry
|
||||
@@ -2687,7 +2605,6 @@ static void sam_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -2704,48 +2621,6 @@ static void sam_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, sam_txtimeout_work, priv, 0);
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
sam_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_poll_process
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_poll_process(FAR struct sam_emac_s *priv)
|
||||
{
|
||||
struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
/* Check if the there are any free TX descriptors. We cannot perform the
|
||||
* TX poll if we do not have buffering for another packet.
|
||||
*/
|
||||
|
||||
if (sam_txfree(priv, EMAC_QUEUE_0) > 0)
|
||||
{
|
||||
/* Update TCP timing states and poll the network for new XMIT data. */
|
||||
|
||||
(void)devif_timer(dev, sam_txpoll);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2765,19 +2640,28 @@ static inline void sam_poll_process(FAR struct sam_emac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
net_lock_t state;
|
||||
struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Check if the there are any free TX descriptors. We cannot perform the
|
||||
* TX poll if we do not have buffering for another packet.
|
||||
*/
|
||||
|
||||
state = net_lock();
|
||||
sam_poll_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
if (sam_txfree(priv, EMAC_QUEUE_0) > 0)
|
||||
{
|
||||
/* Update TCP timing states and poll the network for new XMIT data. */
|
||||
|
||||
(void)devif_timer(dev, sam_txpoll);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_poll_expiry
|
||||
@@ -2801,7 +2685,6 @@ static void sam_poll_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -2820,12 +2703,6 @@ static void sam_poll_expiry(int argc, uint32_t arg, ...)
|
||||
|
||||
(void)wd_start(priv->txpoll, SAM_WDDELAY, sam_poll_expiry, 1, arg);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
sam_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2963,37 +2840,6 @@ static int sam_ifdown(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_txavail_process(FAR struct sam_emac_s *priv)
|
||||
{
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv, EMAC_QUEUE_0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txavail_work
|
||||
*
|
||||
@@ -3011,19 +2857,24 @@ static inline void sam_txavail_process(FAR struct sam_emac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void sam_txavail_work(FAR void *arg)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
state = net_lock();
|
||||
sam_txavail_process(priv);
|
||||
net_unlock(state);
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
net_lock();
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll the network for new XMIT data */
|
||||
|
||||
sam_dopoll(priv, EMAC_QUEUE_0);
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sam_txavail
|
||||
@@ -3048,7 +2899,6 @@ static int sam_txavail(struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct sam_emac_s *priv = (FAR struct sam_emac_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -3061,21 +2911,6 @@ static int sam_txavail(struct net_driver_s *dev)
|
||||
work_queue(ETHWORK, &priv->work, sam_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
irqstate_t flags;
|
||||
|
||||
/* Disable interrupts because this function may be called from interrupt
|
||||
* level processing.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
sam_txavail_process(priv);
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
+52
-215
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/stm32/stm32_eth.c
|
||||
*
|
||||
* Copyright (C) 2011-2012, 2014 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2011-2012, 2014, 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -53,14 +53,11 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/wdog.h>
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/mii.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
|
||||
#if defined(CONFIG_NET_PKT)
|
||||
# include <nuttx/net/pkt.h>
|
||||
#endif
|
||||
@@ -97,13 +94,12 @@
|
||||
* is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# error Work queue support is required
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* Select work queue */
|
||||
/* Select work queue */
|
||||
|
||||
#if defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# if defined(CONFIG_STM32_ETHMAC_HPWORK)
|
||||
# define ETHWORK HPWORK
|
||||
# elif defined(CONFIG_STM32_ETHMAC_LPWORK)
|
||||
@@ -587,9 +583,7 @@ struct stm32_ethmac_s
|
||||
uint8_t fduplex : 1; /* Full (vs. half) duplex */
|
||||
WDOG_ID txpoll; /* TX poll timer */
|
||||
WDOG_ID txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
|
||||
/* This holds the information visible to the NuttX network */
|
||||
|
||||
@@ -662,34 +656,26 @@ static int stm32_recvframe(FAR struct stm32_ethmac_s *priv);
|
||||
static void stm32_receive(FAR struct stm32_ethmac_s *priv);
|
||||
static void stm32_freeframe(FAR struct stm32_ethmac_s *priv);
|
||||
static void stm32_txdone(FAR struct stm32_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void stm32_interrupt_work(FAR void *arg);
|
||||
#endif
|
||||
static int stm32_interrupt(int irq, FAR void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void stm32_txtimeout_process(FAR struct stm32_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void stm32_txtimeout_work(FAR void *arg);
|
||||
#endif
|
||||
static void stm32_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
static inline void stm32_poll_process(FAR struct stm32_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void stm32_poll_work(FAR void *arg);
|
||||
#endif
|
||||
static void stm32_poll_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
|
||||
static int stm32_ifup(struct net_driver_s *dev);
|
||||
static int stm32_ifdown(struct net_driver_s *dev);
|
||||
static inline void stm32_txavail_process(FAR struct stm32_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void stm32_txavail_work(FAR void *arg);
|
||||
#endif
|
||||
static int stm32_txavail(struct net_driver_s *dev);
|
||||
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
static int stm32_addmac(struct net_driver_s *dev, FAR const uint8_t *mac);
|
||||
#endif
|
||||
@@ -1964,27 +1950,33 @@ static void stm32_txdone(FAR struct stm32_ethmac_s *priv)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_interrupt_process
|
||||
* Function: stm32_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void stm32_interrupt_process(FAR struct stm32_ethmac_s *priv)
|
||||
static void stm32_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)arg;
|
||||
uint32_t dmasr;
|
||||
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
net_lock();
|
||||
|
||||
/* Get the DMA interrupt status bits (no MAC interrupts are expected) */
|
||||
|
||||
dmasr = stm32_getreg(STM32_ETH_DMASR);
|
||||
@@ -2056,44 +2048,13 @@ static inline void stm32_interrupt_process(FAR struct stm32_ethmac_s *priv)
|
||||
stm32_putreg(ETH_DMAINT_AIS, STM32_ETH_DMASR);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void stm32_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
stm32_interrupt_process(priv);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts at the NVIC */
|
||||
|
||||
up_enable_irq(STM32_IRQ_ETH);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_interrupt
|
||||
@@ -2115,8 +2076,6 @@ static void stm32_interrupt_work(FAR void *arg)
|
||||
static int stm32_interrupt(int irq, FAR void *context)
|
||||
{
|
||||
FAR struct stm32_ethmac_s *priv = &g_stm32ethmac[0];
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
uint32_t dmasr;
|
||||
|
||||
/* Get the DMA interrupt status bits (no MAC interrupts are expected) */
|
||||
@@ -2152,49 +2111,9 @@ static int stm32_interrupt(int irq, FAR void *context)
|
||||
work_queue(ETHWORK, &priv->work, stm32_interrupt_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
stm32_interrupt_process(priv);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Global interrupts are disabled by the watchdog logic.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void stm32_txtimeout_process(FAR struct stm32_ethmac_s *priv)
|
||||
{
|
||||
/* Then reset the hardware. Just take the interface down, then back
|
||||
* up again.
|
||||
*/
|
||||
|
||||
stm32_ifdown(&priv->dev);
|
||||
stm32_ifup(&priv->dev);
|
||||
|
||||
/* Then poll for new XMIT data */
|
||||
|
||||
stm32_dopoll(priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_txtimeout_work
|
||||
*
|
||||
@@ -2212,19 +2131,21 @@ static inline void stm32_txtimeout_process(FAR struct stm32_ethmac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void stm32_txtimeout_work(FAR void *arg)
|
||||
{
|
||||
FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
/* Reset the hardware. Just take the interface down, then back up again. */
|
||||
|
||||
state = net_lock();
|
||||
stm32_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
stm32_ifdown(&priv->dev);
|
||||
stm32_ifup(&priv->dev);
|
||||
|
||||
/* Then poll for new XMIT data */
|
||||
|
||||
stm32_dopoll(priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_txtimeout_expiry
|
||||
@@ -2251,7 +2172,6 @@ static void stm32_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
|
||||
nerr("ERROR: Timeout!\n");
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -2270,33 +2190,28 @@ static void stm32_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, stm32_txtimeout_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
stm32_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_poll_process
|
||||
* Function: stm32_poll_work
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
* Perform periodic polling from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() as called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void stm32_poll_process(FAR struct stm32_ethmac_s *priv)
|
||||
static void stm32_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)arg;
|
||||
FAR struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
/* Check if the next TX descriptor is owned by the Ethernet DMA or CPU. We
|
||||
@@ -2310,6 +2225,7 @@ static inline void stm32_poll_process(FAR struct stm32_ethmac_s *priv)
|
||||
* CONFIG_STM32_ETH_NTXDESC).
|
||||
*/
|
||||
|
||||
net_lock();
|
||||
if ((priv->txhead->tdes0 & ETH_TDES0_OWN) == 0 &&
|
||||
priv->txhead->tdes2 == 0)
|
||||
{
|
||||
@@ -2345,39 +2261,9 @@ static inline void stm32_poll_process(FAR struct stm32_ethmac_s *priv)
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->txpoll, STM32_WDDELAY, stm32_poll_expiry, 1, priv);
|
||||
net_unlock();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_poll_work
|
||||
*
|
||||
* Description:
|
||||
* Perform periodic polling from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() as called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void stm32_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
|
||||
state = net_lock();
|
||||
stm32_poll_process(priv);
|
||||
net_unlock(state);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_poll_expiry
|
||||
*
|
||||
@@ -2400,7 +2286,6 @@ static void stm32_poll_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -2419,12 +2304,6 @@ static void stm32_poll_expiry(int argc, uint32_t arg, ...)
|
||||
|
||||
(void)wd_start(priv->txpoll, STM32_WDDELAY, stm32_poll_expiry, 1, (uint32_t)priv);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
stm32_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2529,37 +2408,6 @@ static int stm32_ifdown(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void stm32_txavail_process(FAR struct stm32_ethmac_s *priv)
|
||||
{
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll the network for new XMIT data */
|
||||
|
||||
stm32_dopoll(priv);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_txavail_work
|
||||
*
|
||||
@@ -2577,19 +2425,24 @@ static inline void stm32_txavail_process(FAR struct stm32_ethmac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void stm32_txavail_work(FAR void *arg)
|
||||
{
|
||||
FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
state = net_lock();
|
||||
stm32_txavail_process(priv);
|
||||
net_unlock(state);
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
net_lock();
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll the network for new XMIT data */
|
||||
|
||||
stm32_dopoll(priv);
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_txavail
|
||||
@@ -2614,7 +2467,6 @@ static int stm32_txavail(struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct stm32_ethmac_s *priv = (FAR struct stm32_ethmac_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -2627,21 +2479,6 @@ static int stm32_txavail(struct net_driver_s *dev)
|
||||
work_queue(ETHWORK, &priv->work, stm32_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
irqstate_t flags;
|
||||
|
||||
/* Disable interrupts because this function may be called from interrupt
|
||||
* level processing.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
stm32_txavail_process(priv);
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/stm32f7/stm32_ethernet.c
|
||||
*
|
||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -52,14 +52,11 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/wdog.h>
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/mii.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
|
||||
#if defined(CONFIG_NET_PKT)
|
||||
# include <nuttx/net/pkt.h>
|
||||
#endif
|
||||
@@ -98,13 +95,12 @@
|
||||
* is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# error Work queue support is required
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* Select work queue */
|
||||
/* Select work queue */
|
||||
|
||||
#if defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# if defined(CONFIG_STM32F7_ETHMAC_HPWORK)
|
||||
# define ETHWORK HPWORK
|
||||
# elif defined(CONFIG_STM32F7_ETHMAC_LPWORK)
|
||||
@@ -611,9 +607,7 @@ struct stm32_ethmac_s
|
||||
uint8_t intf; /* Ethernet interface number */
|
||||
WDOG_ID txpoll; /* TX poll timer */
|
||||
WDOG_ID txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
|
||||
/* This holds the information visible to the NuttX network */
|
||||
|
||||
@@ -705,35 +699,26 @@ static int stm32_recvframe(struct stm32_ethmac_s *priv);
|
||||
static void stm32_receive(struct stm32_ethmac_s *priv);
|
||||
static void stm32_freeframe(struct stm32_ethmac_s *priv);
|
||||
static void stm32_txdone(struct stm32_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void stm32_interrupt_work(void *arg);
|
||||
#endif
|
||||
static int stm32_interrupt(int irq, void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void stm32_txtimeout_process(struct stm32_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void stm32_txtimeout_work(void *arg);
|
||||
#endif
|
||||
static void stm32_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
static inline void stm32_poll_process(struct stm32_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void stm32_poll_work(void *arg);
|
||||
#endif
|
||||
static void stm32_poll_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
|
||||
static int stm32_ifup(struct net_driver_s *dev);
|
||||
static int stm32_ifdown(struct net_driver_s *dev);
|
||||
static int stm32_ifdown(struct net_driver_s *dev);
|
||||
static inline void stm32_txavail_process(struct stm32_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void stm32_txavail_work(void *arg);
|
||||
#endif
|
||||
static int stm32_txavail(struct net_driver_s *dev);
|
||||
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
static int stm32_addmac(struct net_driver_s *dev, const uint8_t *mac);
|
||||
#endif
|
||||
@@ -2078,27 +2063,33 @@ static void stm32_txdone(struct stm32_ethmac_s *priv)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_interrupt_process
|
||||
* Function: stm32_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void stm32_interrupt_process(struct stm32_ethmac_s *priv)
|
||||
static void stm32_interrupt_work(void *arg)
|
||||
{
|
||||
struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)arg;
|
||||
uint32_t dmasr;
|
||||
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
net_lock();
|
||||
|
||||
/* Get the DMA interrupt status bits (no MAC interrupts are expected) */
|
||||
|
||||
dmasr = stm32_getreg(STM32_ETH_DMASR);
|
||||
@@ -2169,44 +2160,13 @@ static inline void stm32_interrupt_process(struct stm32_ethmac_s *priv)
|
||||
stm32_putreg(ETH_DMAINT_AIS, STM32_ETH_DMASR);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void stm32_interrupt_work(void *arg)
|
||||
{
|
||||
struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
stm32_interrupt_process(priv);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts at the NVIC */
|
||||
|
||||
up_enable_irq(STM32_IRQ_ETH);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_interrupt
|
||||
@@ -2228,8 +2188,6 @@ static void stm32_interrupt_work(void *arg)
|
||||
static int stm32_interrupt(int irq, void *context)
|
||||
{
|
||||
struct stm32_ethmac_s *priv = &g_stm32ethmac[0];
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
uint32_t dmasr;
|
||||
|
||||
/* Get the DMA interrupt status bits (no MAC interrupts are expected) */
|
||||
@@ -2265,49 +2223,9 @@ static int stm32_interrupt(int irq, void *context)
|
||||
work_queue(ETHWORK, &priv->work, stm32_interrupt_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
stm32_interrupt_process(priv);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Global interrupts are disabled by the watchdog logic.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void stm32_txtimeout_process(struct stm32_ethmac_s *priv)
|
||||
{
|
||||
/* Then reset the hardware. Just take the interface down, then back
|
||||
* up again.
|
||||
*/
|
||||
|
||||
stm32_ifdown(&priv->dev);
|
||||
stm32_ifup(&priv->dev);
|
||||
|
||||
/* Then poll for new XMIT data */
|
||||
|
||||
stm32_dopoll(priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_txtimeout_work
|
||||
*
|
||||
@@ -2325,19 +2243,21 @@ static inline void stm32_txtimeout_process(struct stm32_ethmac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void stm32_txtimeout_work(void *arg)
|
||||
{
|
||||
struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
/* Reset the hardware. Just take the interface down, then back up again. */
|
||||
|
||||
state = net_lock();
|
||||
stm32_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
stm32_ifdown(&priv->dev);
|
||||
stm32_ifup(&priv->dev);
|
||||
|
||||
/* Then poll for new XMIT data */
|
||||
|
||||
stm32_dopoll(priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_txtimeout_expiry
|
||||
@@ -2364,7 +2284,6 @@ static void stm32_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
|
||||
nerr("ERROR: Timeout!\n");
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -2383,33 +2302,28 @@ static void stm32_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, stm32_txtimeout_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
stm32_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_poll_process
|
||||
* Function: stm32_poll_work
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
* Perform periodic polling from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() as called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void stm32_poll_process(struct stm32_ethmac_s *priv)
|
||||
static void stm32_poll_work(void *arg)
|
||||
{
|
||||
struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)arg;
|
||||
struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
/* Check if the next TX descriptor is owned by the Ethernet DMA or CPU. We
|
||||
@@ -2423,6 +2337,7 @@ static inline void stm32_poll_process(struct stm32_ethmac_s *priv)
|
||||
* CONFIG_STM32F7_ETH_NTXDESC).
|
||||
*/
|
||||
|
||||
net_lock();
|
||||
if ((priv->txhead->tdes0 & ETH_TDES0_OWN) == 0 &&
|
||||
priv->txhead->tdes2 == 0)
|
||||
{
|
||||
@@ -2458,39 +2373,9 @@ static inline void stm32_poll_process(struct stm32_ethmac_s *priv)
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->txpoll, STM32_WDDELAY, stm32_poll_expiry, 1, priv);
|
||||
net_unlock();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_poll_work
|
||||
*
|
||||
* Description:
|
||||
* Perform periodic polling from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() as called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void stm32_poll_work(void *arg)
|
||||
{
|
||||
struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
|
||||
state = net_lock();
|
||||
stm32_poll_process(priv);
|
||||
net_unlock(state);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_poll_expiry
|
||||
*
|
||||
@@ -2513,7 +2398,6 @@ static void stm32_poll_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -2532,12 +2416,6 @@ static void stm32_poll_expiry(int argc, uint32_t arg, ...)
|
||||
|
||||
(void)wd_start(priv->txpoll, STM32_WDDELAY, stm32_poll_expiry, 1, (uint32_t)priv);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
stm32_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2642,38 +2520,6 @@ static int stm32_ifdown(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void stm32_txavail_process(struct stm32_ethmac_s *priv)
|
||||
{
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll the network for new XMIT data */
|
||||
|
||||
stm32_dopoll(priv);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_txavail_work
|
||||
*
|
||||
@@ -2691,19 +2537,24 @@ static inline void stm32_txavail_process(struct stm32_ethmac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void stm32_txavail_work(void *arg)
|
||||
{
|
||||
struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
state = net_lock();
|
||||
stm32_txavail_process(priv);
|
||||
net_unlock(state);
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
net_lock();
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll the network for new XMIT data */
|
||||
|
||||
stm32_dopoll(priv);
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: stm32_txavail
|
||||
@@ -2728,7 +2579,6 @@ static int stm32_txavail(struct net_driver_s *dev)
|
||||
{
|
||||
struct stm32_ethmac_s *priv = (struct stm32_ethmac_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -2741,21 +2591,6 @@ static int stm32_txavail(struct net_driver_s *dev)
|
||||
work_queue(ETHWORK, &priv->work, stm32_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
irqstate_t flags;
|
||||
|
||||
/* Disable interrupts because this function may be called from interrupt
|
||||
* level processing.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
stm32_txavail_process(priv);
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,10 +52,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
#include <nuttx/wqueue.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
@@ -80,13 +77,12 @@
|
||||
* is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# error Work queue support is required in this configuration (CONFIG_SCHED_WORKQUEUE)
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* Use the low priority work queue if possible */
|
||||
/* Use the low priority work queue if possible */
|
||||
|
||||
#if defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# if defined(CONFIG_TIVA_ETHERNET_HPWORK)
|
||||
# define ETHWORK HPWORK
|
||||
# elif defined(CONFIG_TIVA_ETHERNET_LPWORK)
|
||||
@@ -206,9 +202,7 @@ struct tiva_driver_s
|
||||
bool ld_bifup; /* true:ifup false:ifdown */
|
||||
WDOG_ID ld_txpoll; /* TX poll timer */
|
||||
WDOG_ID ld_txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s ld_work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
|
||||
/* This holds the information visible to the NuttX network */
|
||||
|
||||
@@ -256,24 +250,15 @@ static int tiva_txpoll(struct net_driver_s *dev);
|
||||
static void tiva_receive(struct tiva_driver_s *priv);
|
||||
static void tiva_txdone(struct tiva_driver_s *priv);
|
||||
|
||||
static inline void tiva_interrupt_process(struct tiva_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void tiva_interrupt_work(void *arg);
|
||||
#endif
|
||||
static int tiva_interrupt(int irq, void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void tiva_txtimeout_process(struct tiva_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void tiva_txtimeout_work(void *arg);
|
||||
#endif
|
||||
static void tiva_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
static inline void tiva_poll_process(struct tiva_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void tiva_poll_work(void *arg);
|
||||
#endif
|
||||
static void tiva_poll_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
@@ -281,11 +266,7 @@ static void tiva_poll_expiry(int argc, uint32_t arg, ...);
|
||||
static int tiva_ifup(struct net_driver_s *dev);
|
||||
static int tiva_ifdown(struct net_driver_s *dev);
|
||||
|
||||
|
||||
static inline void tiva_txavail_process(struct tiva_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void tiva_txavail_work(void *arg);
|
||||
#endif
|
||||
static int tiva_txavail(struct net_driver_s *dev);
|
||||
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
@@ -963,27 +944,31 @@ static void tiva_txdone(struct tiva_driver_s *priv)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_interrupt_process
|
||||
* Function: tiva_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* The network is locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void tiva_interrupt_process(struct tiva_driver_s *priv)
|
||||
static void tiva_interrupt_work(void *arg)
|
||||
{
|
||||
struct tiva_driver_s *priv = (struct tiva_driver_s *)arg;
|
||||
uint32_t ris;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
net_lock();
|
||||
|
||||
/* Read the raw interrupt status register */
|
||||
|
||||
ris = tiva_ethin(priv, TIVA_MAC_RIS_OFFSET);
|
||||
@@ -1038,36 +1023,8 @@ static inline void tiva_interrupt_process(struct tiva_driver_s *priv)
|
||||
|
||||
tiva_txdone(priv);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* The network is locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void tiva_interrupt_work(void *arg)
|
||||
{
|
||||
struct tiva_driver_s *priv = (struct tiva_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
tiva_interrupt_process(priv);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts */
|
||||
|
||||
@@ -1077,7 +1034,6 @@ static void tiva_interrupt_work(void *arg)
|
||||
up_disable_irq(TIVA_IRQ_ETHCON);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_interrupt
|
||||
@@ -1107,7 +1063,6 @@ static int tiva_interrupt(int irq, void *context)
|
||||
priv = &g_lm3sdev[0];
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. Because Ethernet interrupts are
|
||||
* also disabled if the TX timeout event occurs, there can be no race
|
||||
* condition here.
|
||||
@@ -1145,51 +1100,9 @@ static int tiva_interrupt(int irq, void *context)
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->ld_work, tiva_interrupt_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
tiva_interrupt_process(priv);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void tiva_txtimeout_process(struct tiva_driver_s *priv)
|
||||
{
|
||||
/* Increment statistics */
|
||||
|
||||
nerr("ERROR: Tx timeout\n");
|
||||
NETDEV_TXTIMEOUTS(&priv->ld_dev);
|
||||
|
||||
/* Then reset the hardware */
|
||||
|
||||
DEBUGASSERT(priv->ld_bifup);
|
||||
tiva_ifdown(&priv->ld_dev);
|
||||
tiva_ifup(&priv->ld_dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
(void)devif_poll(&priv->ld_dev, tiva_txpoll);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_txtimeout_work
|
||||
*
|
||||
@@ -1207,19 +1120,27 @@ static inline void tiva_txtimeout_process(struct tiva_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void tiva_txtimeout_work(void *arg)
|
||||
{
|
||||
struct tiva_driver_s *priv = (struct tiva_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
/* Increment statistics */
|
||||
|
||||
state = net_lock();
|
||||
tiva_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
nerr("ERROR: Tx timeout\n");
|
||||
NETDEV_TXTIMEOUTS(&priv->ld_dev);
|
||||
|
||||
/* Then reset the hardware */
|
||||
|
||||
DEBUGASSERT(priv->ld_bifup);
|
||||
tiva_ifdown(&priv->ld_dev);
|
||||
tiva_ifup(&priv->ld_dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
(void)devif_poll(&priv->ld_dev, tiva_txpoll);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_txtimeout_expiry
|
||||
@@ -1244,7 +1165,6 @@ static void tiva_txtimeout_expiry(int argc, wdparm_t arg, ...)
|
||||
{
|
||||
struct tiva_driver_s *priv = (struct tiva_driver_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -1265,53 +1185,6 @@ static void tiva_txtimeout_expiry(int argc, wdparm_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->ld_work, tiva_txtimeout_work, priv, 0);
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
tiva_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_poll_process
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void tiva_poll_process(struct tiva_driver_s *priv)
|
||||
{
|
||||
/* Check if we can send another Tx packet now. The NEWTX bit initiates an
|
||||
* Ethernet transmission once the packet has been placed in the TX FIFO.
|
||||
* This bit is cleared once the transmission has been completed.
|
||||
*
|
||||
* NOTE: This can cause missing poll cycles and, hence, some timing
|
||||
* inaccuracies.
|
||||
*/
|
||||
|
||||
if ((tiva_ethin(priv, TIVA_MAC_TR_OFFSET) & MAC_TR_NEWTX) == 0)
|
||||
{
|
||||
/* If so, update TCP timing states and poll the network for new XMIT
|
||||
* data.
|
||||
*/
|
||||
|
||||
(void)devif_timer(&priv->ld_dev, tiva_txpoll);
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->ld_txpoll, TIVA_WDDELAY, tiva_poll_expiry,
|
||||
1, priv);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -1331,19 +1204,35 @@ static inline void tiva_poll_process(struct tiva_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void tiva_poll_work(void *arg)
|
||||
{
|
||||
struct tiva_driver_s *priv = (struct tiva_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Check if we can send another Tx packet now. The NEWTX bit initiates an
|
||||
* Ethernet transmission once the packet has been placed in the TX FIFO.
|
||||
* This bit is cleared once the transmission has been completed.
|
||||
*
|
||||
* NOTE: This can cause missing poll cycles and, hence, some timing
|
||||
* inaccuracies.
|
||||
*/
|
||||
|
||||
state = net_lock();
|
||||
tiva_poll_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
if ((tiva_ethin(priv, TIVA_MAC_TR_OFFSET) & MAC_TR_NEWTX) == 0)
|
||||
{
|
||||
/* If so, update TCP timing states and poll the network for new XMIT
|
||||
* data.
|
||||
*/
|
||||
|
||||
(void)devif_timer(&priv->ld_dev, tiva_txpoll);
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->ld_txpoll, TIVA_WDDELAY, tiva_poll_expiry,
|
||||
1, priv);
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_poll_expiry
|
||||
@@ -1367,7 +1256,6 @@ static void tiva_poll_expiry(int argc, wdparm_t arg, ...)
|
||||
{
|
||||
struct tiva_driver_s *priv = (struct tiva_driver_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -1386,12 +1274,6 @@ static void tiva_poll_expiry(int argc, wdparm_t arg, ...)
|
||||
|
||||
(void)wd_start(priv->ld_txpoll, TIVA_WDDELAY, tiva_poll_expiry, 1, arg);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
tiva_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -1633,43 +1515,6 @@ static int tiva_ifdown(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void tiva_txavail_process(struct tiva_driver_s *priv)
|
||||
{
|
||||
/* Ignore the notification if the interface is not yet up or if the Tx FIFO
|
||||
* hardware is not available at this time. The NEWTX bit initiates an
|
||||
* Ethernet transmission once the packet has been placed in the TX FIFO.
|
||||
* This bit is cleared once the transmission has been completed. When the
|
||||
* transmission completes, tiva_txdone() will be called and the Tx polling
|
||||
* will occur at that time.
|
||||
*/
|
||||
|
||||
if (priv->ld_bifup && (tiva_ethin(priv, TIVA_MAC_TR_OFFSET) & MAC_TR_NEWTX) == 0)
|
||||
{
|
||||
/* If the interface is up and we can use the Tx FIFO, then poll the network
|
||||
* for new Tx data
|
||||
*/
|
||||
|
||||
(void)devif_poll(&priv->ld_dev, tiva_txpoll);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_txavail_work
|
||||
*
|
||||
@@ -1687,19 +1532,30 @@ static inline void tiva_txavail_process(struct tiva_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void tiva_txavail_work(void *arg)
|
||||
{
|
||||
struct tiva_driver_s *priv = (struct tiva_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Ignore the notification if the interface is not yet up or if the Tx FIFO
|
||||
* hardware is not available at this time. The NEWTX bit initiates an
|
||||
* Ethernet transmission once the packet has been placed in the TX FIFO.
|
||||
* This bit is cleared once the transmission has been completed. When the
|
||||
* transmission completes, tiva_txdone() will be called and the Tx polling
|
||||
* will occur at that time.
|
||||
*/
|
||||
|
||||
state = net_lock();
|
||||
tiva_txavail_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
if (priv->ld_bifup && (tiva_ethin(priv, TIVA_MAC_TR_OFFSET) & MAC_TR_NEWTX) == 0)
|
||||
{
|
||||
/* If the interface is up and we can use the Tx FIFO, then poll the network
|
||||
* for new Tx data
|
||||
*/
|
||||
|
||||
(void)devif_poll(&priv->ld_dev, tiva_txpoll);
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_txavail
|
||||
@@ -1724,7 +1580,6 @@ static int tiva_txavail(struct net_driver_s *dev)
|
||||
{
|
||||
struct tiva_driver_s *priv = (struct tiva_driver_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -1737,21 +1592,6 @@ static int tiva_txavail(struct net_driver_s *dev)
|
||||
work_queue(ETHWORK, &priv->ld_work, tiva_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
irqstate_t flags;
|
||||
|
||||
/* Disable interrupts because this function may be called from interrupt
|
||||
* level processing.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
tiva_txavail_process(priv);
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,11 +53,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/wdog.h>
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/mii.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
@@ -102,13 +98,12 @@
|
||||
* is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# error Work queue support is required
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* Select work queue */
|
||||
/* Select work queue */
|
||||
|
||||
#if defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# if defined(CONFIG_TIVA_ETHERNET_HPWORK)
|
||||
# define ETHWORK HPWORK
|
||||
# elif defined(CONFIG_TIVA_ETHERNET_LPWORK)
|
||||
@@ -631,9 +626,7 @@ struct tiva_ethmac_s
|
||||
uint8_t fduplex : 1; /* Full (vs. half) duplex */
|
||||
WDOG_ID txpoll; /* TX poll timer */
|
||||
WDOG_ID txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
#ifdef CONFIG_TIVA_PHY_INTERRUPTS
|
||||
xcpt_t handler; /* Attached PHY interrupt handler */
|
||||
#endif
|
||||
@@ -709,35 +702,26 @@ static int tiva_recvframe(FAR struct tiva_ethmac_s *priv);
|
||||
static void tiva_receive(FAR struct tiva_ethmac_s *priv);
|
||||
static void tiva_freeframe(FAR struct tiva_ethmac_s *priv);
|
||||
static void tiva_txdone(FAR struct tiva_ethmac_s *priv);
|
||||
static inline void tiva_interrupt_process(FAR struct tiva_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void tiva_interrupt_work(FAR void *arg);
|
||||
#endif
|
||||
static int tiva_interrupt(int irq, FAR void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void tiva_txtimeout_process(FAR struct tiva_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void tiva_txtimeout_work(FAR void *arg);
|
||||
#endif
|
||||
static void tiva_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
static inline void tiva_poll_process(FAR struct tiva_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void tiva_poll_work(FAR void *arg);
|
||||
#endif
|
||||
static void tiva_poll_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
|
||||
static int tiva_ifup(struct net_driver_s *dev);
|
||||
static int tiva_ifdown(struct net_driver_s *dev);
|
||||
static inline void tiva_txavail_process(FAR struct tiva_ethmac_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void tiva_txavail_work(FAR void *arg);
|
||||
#endif
|
||||
static int tiva_txavail(struct net_driver_s *dev);
|
||||
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
static int tiva_addmac(struct net_driver_s *dev, FAR const uint8_t *mac);
|
||||
#endif
|
||||
@@ -1994,27 +1978,33 @@ static void tiva_txdone(FAR struct tiva_ethmac_s *priv)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_interrupt_process
|
||||
* Function: tiva_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void tiva_interrupt_process(FAR struct tiva_ethmac_s *priv)
|
||||
static void tiva_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)arg;
|
||||
uint32_t dmaris;
|
||||
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
net_lock();
|
||||
|
||||
/* Get the DMA interrupt status bits (no MAC interrupts are expected) */
|
||||
|
||||
dmaris = tiva_getreg(TIVA_EMAC_DMARIS);
|
||||
@@ -2086,44 +2076,13 @@ static inline void tiva_interrupt_process(FAR struct tiva_ethmac_s *priv)
|
||||
tiva_putreg(EMAC_DMAINT_AIS, TIVA_EMAC_DMARIS);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void tiva_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
tiva_interrupt_process(priv);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts at the NVIC */
|
||||
|
||||
up_enable_irq(TIVA_IRQ_ETHCON);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_interrupt
|
||||
@@ -2145,8 +2104,6 @@ static void tiva_interrupt_work(FAR void *arg)
|
||||
static int tiva_interrupt(int irq, FAR void *context)
|
||||
{
|
||||
FAR struct tiva_ethmac_s *priv = &g_tiva_ethmac[0];
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
uint32_t dmaris;
|
||||
|
||||
/* Get the raw interrupt status. */
|
||||
@@ -2182,12 +2139,6 @@ static int tiva_interrupt(int irq, FAR void *context)
|
||||
work_queue(ETHWORK, &priv->work, tiva_interrupt_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
tiva_interrupt_process(priv);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TIVA_PHY_INTERRUPTS
|
||||
/* Check for pending PHY interrupts */
|
||||
|
||||
@@ -2209,38 +2160,6 @@ static int tiva_interrupt(int irq, FAR void *context)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Global interrupts are disabled by the watchdog logic.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void tiva_txtimeout_process(FAR struct tiva_ethmac_s *priv)
|
||||
{
|
||||
/* Reset the hardware. Just take the interface down, then back up again. */
|
||||
|
||||
tiva_ifdown(&priv->dev);
|
||||
tiva_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
tiva_dopoll(priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_txtimeout_work
|
||||
*
|
||||
@@ -2258,19 +2177,21 @@ static inline void tiva_txtimeout_process(FAR struct tiva_ethmac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void tiva_txtimeout_work(FAR void *arg)
|
||||
{
|
||||
FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
/* Reset the hardware. Just take the interface down, then back up again. */
|
||||
|
||||
state = net_lock();
|
||||
tiva_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
tiva_ifdown(&priv->dev);
|
||||
tiva_ifup(&priv->dev);
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
tiva_dopoll(priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_txtimeout_expiry
|
||||
@@ -2297,7 +2218,6 @@ static void tiva_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
|
||||
nerr("ERROR: Timeout!\n");
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -2316,33 +2236,28 @@ static void tiva_txtimeout_expiry(int argc, uint32_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->work, tiva_txtimeout_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
tiva_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_poll_process
|
||||
* Function: tiva_poll_work
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
* Perform periodic polling from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() as called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void tiva_poll_process(FAR struct tiva_ethmac_s *priv)
|
||||
static void tiva_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)arg;
|
||||
FAR struct net_driver_s *dev = &priv->dev;
|
||||
|
||||
/* Check if the next TX descriptor is owned by the Ethernet DMA or CPU. We
|
||||
@@ -2356,6 +2271,7 @@ static inline void tiva_poll_process(FAR struct tiva_ethmac_s *priv)
|
||||
* CONFIG_TIVA_EMAC_NTXDESC).
|
||||
*/
|
||||
|
||||
net_lock();
|
||||
if ((priv->txhead->tdes0 & EMAC_TDES0_OWN) == 0 &&
|
||||
priv->txhead->tdes2 == 0)
|
||||
{
|
||||
@@ -2391,39 +2307,9 @@ static inline void tiva_poll_process(FAR struct tiva_ethmac_s *priv)
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->txpoll, TIVA_WDDELAY, tiva_poll_expiry, 1, (uint32_t)priv);
|
||||
net_unlock();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_poll_work
|
||||
*
|
||||
* Description:
|
||||
* Perform periodic polling from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() as called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* Ethernet interrupts are disabled
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void tiva_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
|
||||
state = net_lock();
|
||||
tiva_poll_process(priv);
|
||||
net_unlock(state);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_poll_expiry
|
||||
*
|
||||
@@ -2446,7 +2332,6 @@ static void tiva_poll_expiry(int argc, uint32_t arg, ...)
|
||||
{
|
||||
FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -2465,12 +2350,6 @@ static void tiva_poll_expiry(int argc, uint32_t arg, ...)
|
||||
|
||||
(void)wd_start(priv->txpoll, TIVA_WDDELAY, tiva_poll_expiry, 1, (uint32_t)priv);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
tiva_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2575,37 +2454,6 @@ static int tiva_ifdown(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void tiva_txavail_process(FAR struct tiva_ethmac_s *priv)
|
||||
{
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll the network for new XMIT data */
|
||||
|
||||
tiva_dopoll(priv);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_txavail_work
|
||||
*
|
||||
@@ -2623,19 +2471,24 @@ static inline void tiva_txavail_process(FAR struct tiva_ethmac_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void tiva_txavail_work(FAR void *arg)
|
||||
{
|
||||
FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
ninfo("ifup: %d\n", priv->ifup);
|
||||
|
||||
state = net_lock();
|
||||
tiva_txavail_process(priv);
|
||||
net_unlock(state);
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
net_lock();
|
||||
if (priv->ifup)
|
||||
{
|
||||
/* Poll the network for new XMIT data */
|
||||
|
||||
tiva_dopoll(priv);
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: tiva_txavail
|
||||
@@ -2660,7 +2513,6 @@ static int tiva_txavail(struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -2673,21 +2525,6 @@ static int tiva_txavail(struct net_driver_s *dev)
|
||||
work_queue(ETHWORK, &priv->work, tiva_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
irqstate_t flags;
|
||||
|
||||
/* Disable interrupts because this function may be called from interrupt
|
||||
* level processing.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
tiva_txavail_process(priv);
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,11 +55,7 @@
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/wdog.h>
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/mii.h>
|
||||
#include <nuttx/net/netconfig.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
@@ -90,13 +86,12 @@
|
||||
* is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# error Work queue support is required in this configuration (CONFIG_SCHED_WORKQUEUE)
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* Use the low priority work queue if possible */
|
||||
/* Use the low priority work queue if possible */
|
||||
|
||||
#if defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# if defined(CONFIG_PIC32MX_ETHERNET_HPWORK)
|
||||
# define ETHWORK HPWORK
|
||||
# elif defined(CONFIG_PIC32MX_ETHERNET_LPWORK)
|
||||
@@ -326,9 +321,7 @@ struct pic32mx_driver_s
|
||||
uint32_t pd_inten; /* Shadow copy of INTEN register */
|
||||
WDOG_ID pd_txpoll; /* TX poll timer */
|
||||
WDOG_ID pd_txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s pd_work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
|
||||
sq_queue_t pd_freebuffers; /* The free buffer list */
|
||||
|
||||
@@ -401,24 +394,15 @@ static void pic32mx_response(struct pic32mx_driver_s *priv);
|
||||
static void pic32mx_rxdone(struct pic32mx_driver_s *priv);
|
||||
static void pic32mx_txdone(struct pic32mx_driver_s *priv);
|
||||
|
||||
static inline void pic32mx_interrupt_process(struct pic32mx_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void pic32mx_interrupt_work(void *arg);
|
||||
#endif
|
||||
static int pic32mx_interrupt(int irq, void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void pic32mx_txtimeout_process(struct pic32mx_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void pic32mx_txtimeout_work(void *arg);
|
||||
#endif
|
||||
static void pic32mx_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
static inline void pic32mx_poll_process(struct pic32mx_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void pic32mx_poll_work(void *arg);
|
||||
#endif
|
||||
static void pic32mx_poll_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
@@ -426,10 +410,7 @@ static void pic32mx_poll_expiry(int argc, uint32_t arg, ...);
|
||||
static int pic32mx_ifup(struct net_driver_s *dev);
|
||||
static int pic32mx_ifdown(struct net_driver_s *dev);
|
||||
|
||||
static inline void pic32mx_txavail_process(struct pic32mx_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void pic32mx_txavail_work(void *arg);
|
||||
#endif
|
||||
static int pic32mx_txavail(struct net_driver_s *dev);
|
||||
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
@@ -1682,27 +1663,31 @@ static void pic32mx_txdone(struct pic32mx_driver_s *priv)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mx_interrupt_process
|
||||
* Function: pic32mx_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* The network is locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void pic32mx_interrupt_process(struct pic32mx_driver_s *priv)
|
||||
static void pic32mx_interrupt_work(void *arg)
|
||||
{
|
||||
struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)arg;
|
||||
uint32_t status;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
net_lock();
|
||||
|
||||
/* Get the interrupt status (zero means no interrupts pending). */
|
||||
|
||||
status = pic32mx_getreg(PIC32MX_ETH_IRQ);
|
||||
@@ -1840,36 +1825,7 @@ static inline void pic32mx_interrupt_process(struct pic32mx_driver_s *priv)
|
||||
#else
|
||||
up_clrpend_irq(PIC32MX_IRQSRC_ETH);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mx_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* The network is locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void pic32mx_interrupt_work(void *arg)
|
||||
{
|
||||
struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
pic32mx_interrupt_process(priv);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts */
|
||||
|
||||
@@ -1879,7 +1835,6 @@ static void pic32mx_interrupt_work(void *arg)
|
||||
up_enable_irq(PIC32MX_IRQSRC_ETH);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mx_interrupt
|
||||
@@ -1909,7 +1864,6 @@ static int pic32mx_interrupt(int irq, void *context)
|
||||
priv = &g_ethdrvr[0];
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. Because Ethernet interrupts are
|
||||
* also disabled if the TX timeout event occurs, there can be no race
|
||||
* condition here.
|
||||
@@ -1944,54 +1898,9 @@ static int pic32mx_interrupt(int irq, void *context)
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->pd_work, pic32mx_interrupt_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
pic32mx_interrupt_process(priv);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mx_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void pic32mx_txtimeout_process(struct pic32mx_driver_s *priv)
|
||||
{
|
||||
/* Increment statistics and dump debug info */
|
||||
|
||||
NETDEV_TXTIMEOUTS(&priv->pd_dev);
|
||||
if (priv->pd_ifup)
|
||||
{
|
||||
/* Then reset the hardware. ifup() will reset the interface, then bring
|
||||
* it back up.
|
||||
*/
|
||||
|
||||
(void)pic32mx_ifup(&priv->pd_dev);
|
||||
|
||||
/* Then poll the network for new XMIT data (We are guaranteed to have
|
||||
* a free buffer here).
|
||||
*/
|
||||
|
||||
pic32mx_poll(priv);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mx_txtimeout_work
|
||||
*
|
||||
@@ -2009,19 +1918,31 @@ static inline void pic32mx_txtimeout_process(struct pic32mx_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void pic32mx_txtimeout_work(void *arg)
|
||||
{
|
||||
struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
/* Increment statistics and dump debug info */
|
||||
|
||||
state = net_lock();
|
||||
pic32mx_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
NETDEV_TXTIMEOUTS(&priv->pd_dev);
|
||||
if (priv->pd_ifup)
|
||||
{
|
||||
/* Then reset the hardware. ifup() will reset the interface, then bring
|
||||
* it back up.
|
||||
*/
|
||||
|
||||
(void)pic32mx_ifup(&priv->pd_dev);
|
||||
|
||||
/* Then poll the network for new XMIT data (We are guaranteed to have
|
||||
* a free buffer here).
|
||||
*/
|
||||
|
||||
pic32mx_poll(priv);
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mx_txtimeout_expiry
|
||||
@@ -2046,7 +1967,6 @@ static void pic32mx_txtimeout_expiry(int argc, wdparm_t arg, ...)
|
||||
{
|
||||
struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -2067,50 +1987,6 @@ static void pic32mx_txtimeout_expiry(int argc, wdparm_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->pd_work, pic32mx_txtimeout_work, priv, 0);
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
pic32mx_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mx_poll_process
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void pic32mx_poll_process(struct pic32mx_driver_s *priv)
|
||||
{
|
||||
/* Check if the next Tx descriptor is available. We cannot perform the Tx
|
||||
* poll if we are unable to accept another packet for transmission.
|
||||
*/
|
||||
|
||||
if (pic32mx_txdesc(priv) != NULL)
|
||||
{
|
||||
/* If so, update TCP timing states and poll the network for new XMIT data. Hmmm..
|
||||
* might be bug here. Does this mean if there is a transmit in progress,
|
||||
* we will missing TCP time state updates?
|
||||
*/
|
||||
|
||||
pic32mx_timerpoll(priv);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->pd_txpoll, PIC32MX_WDDELAY, pic32mx_poll_expiry,
|
||||
1, priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2130,19 +2006,31 @@ static inline void pic32mx_poll_process(struct pic32mx_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void pic32mx_poll_work(void *arg)
|
||||
{
|
||||
struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Check if the next Tx descriptor is available. We cannot perform the Tx
|
||||
* poll if we are unable to accept another packet for transmission.
|
||||
*/
|
||||
|
||||
state = net_lock();
|
||||
pic32mx_poll_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
if (pic32mx_txdesc(priv) != NULL)
|
||||
{
|
||||
/* If so, update TCP timing states and poll the network for new XMIT data. Hmmm..
|
||||
* might be bug here. Does this mean if there is a transmit in progress,
|
||||
* we will missing TCP time state updates?
|
||||
*/
|
||||
|
||||
pic32mx_timerpoll(priv);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->pd_txpoll, PIC32MX_WDDELAY, pic32mx_poll_expiry,
|
||||
1, priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mx_poll_expiry
|
||||
@@ -2166,7 +2054,6 @@ static void pic32mx_poll_expiry(int argc, wdparm_t arg, ...)
|
||||
{
|
||||
struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -2186,12 +2073,6 @@ static void pic32mx_poll_expiry(int argc, wdparm_t arg, ...)
|
||||
(void)wd_start(priv->pd_txpoll, PIC32MX_WDDELAY, pic32mx_poll_expiry,
|
||||
1, arg);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
pic32mx_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2541,42 +2422,6 @@ static int pic32mx_ifdown(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mx_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void pic32mx_txavail_process(struct pic32mx_driver_s *priv)
|
||||
{
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
if (priv->pd_ifup)
|
||||
{
|
||||
/* Check if the next Tx descriptor is available. */
|
||||
|
||||
if (pic32mx_txdesc(priv) != NULL)
|
||||
{
|
||||
/* If so, then poll the network for new XMIT data. First allocate a buffer
|
||||
* to perform the poll
|
||||
*/
|
||||
|
||||
pic32mx_poll(priv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mx_txavail_work
|
||||
*
|
||||
@@ -2594,19 +2439,29 @@ static inline void pic32mx_txavail_process(struct pic32mx_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void pic32mx_txavail_work(void *arg)
|
||||
{
|
||||
struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
state = net_lock();
|
||||
pic32mx_txavail_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
if (priv->pd_ifup)
|
||||
{
|
||||
/* Check if the next Tx descriptor is available. */
|
||||
|
||||
if (pic32mx_txdesc(priv) != NULL)
|
||||
{
|
||||
/* If so, then poll the network for new XMIT data. First allocate a buffer
|
||||
* to perform the poll
|
||||
*/
|
||||
|
||||
pic32mx_poll(priv);
|
||||
}
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mx_txavail
|
||||
@@ -2631,7 +2486,6 @@ static int pic32mx_txavail(struct net_driver_s *dev)
|
||||
{
|
||||
struct pic32mx_driver_s *priv = (struct pic32mx_driver_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -2644,21 +2498,6 @@ static int pic32mx_txavail(struct net_driver_s *dev)
|
||||
work_queue(ETHWORK, &priv->pd_work, pic32mx_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
irqstate_t flags;
|
||||
|
||||
/* Disable interrupts because this function may be called from interrupt
|
||||
* level processing.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
pic32mx_txavail_process(priv);
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,11 +55,7 @@
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/wdog.h>
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/mii.h>
|
||||
#include <nuttx/net/netconfig.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
@@ -90,13 +86,12 @@
|
||||
* is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# error Work queue support is required in this configuration (CONFIG_SCHED_WORKQUEUE)
|
||||
#endif
|
||||
#else
|
||||
|
||||
/* Use the low priority work queue if possible */
|
||||
/* Use the low priority work queue if possible */
|
||||
|
||||
#if defined(CONFIG_SCHED_WORKQUEUE)
|
||||
# if defined(CONFIG_PIC32MZ_ETHERNET_HPWORK)
|
||||
# define ETHWORK HPWORK
|
||||
# elif defined(CONFIG_PIC32MZ_ETHERNET_LPWORK)
|
||||
@@ -353,9 +348,7 @@ struct pic32mz_driver_s
|
||||
uint32_t pd_inten; /* Shadow copy of INTEN register */
|
||||
WDOG_ID pd_txpoll; /* TX poll timer */
|
||||
WDOG_ID pd_txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s pd_work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
|
||||
sq_queue_t pd_freebuffers; /* The free buffer list */
|
||||
|
||||
@@ -428,24 +421,15 @@ static void pic32mz_response(struct pic32mz_driver_s *priv);
|
||||
static void pic32mz_rxdone(struct pic32mz_driver_s *priv);
|
||||
static void pic32mz_txdone(struct pic32mz_driver_s *priv);
|
||||
|
||||
static inline void pic32mz_interrupt_process(struct pic32mz_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void pic32mz_interrupt_work(void *arg);
|
||||
#endif
|
||||
static int pic32mz_interrupt(int irq, void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void pic32mz_txtimeout_process(struct pic32mz_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void pic32mz_txtimeout_work(void *arg);
|
||||
#endif
|
||||
static void pic32mz_txtimeout_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
static inline void pic32mz_poll_process(struct pic32mz_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void pic32mz_poll_work(void *arg);
|
||||
#endif
|
||||
static void pic32mz_poll_expiry(int argc, uint32_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
@@ -453,10 +437,7 @@ static void pic32mz_poll_expiry(int argc, uint32_t arg, ...);
|
||||
static int pic32mz_ifup(struct net_driver_s *dev);
|
||||
static int pic32mz_ifdown(struct net_driver_s *dev);
|
||||
|
||||
static inline void pic32mz_txavail_process(struct pic32mz_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void pic32mz_txavail_work(void *arg);
|
||||
#endif
|
||||
static int pic32mz_txavail(struct net_driver_s *dev);
|
||||
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
@@ -1709,27 +1690,31 @@ static void pic32mz_txdone(struct pic32mz_driver_s *priv)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mz_interrupt_process
|
||||
* Function: pic32mz_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* The network is locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void pic32mz_interrupt_process(struct pic32mz_driver_s *priv)
|
||||
static void pic32mz_interrupt_work(void *arg)
|
||||
{
|
||||
struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)arg;
|
||||
uint32_t status;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
net_lock();
|
||||
|
||||
/* Get the interrupt status (zero means no interrupts pending). */
|
||||
|
||||
status = pic32mz_getreg(PIC32MZ_ETH_IRQ);
|
||||
@@ -1867,36 +1852,7 @@ static inline void pic32mz_interrupt_process(struct pic32mz_driver_s *priv)
|
||||
#else
|
||||
up_clrpend_irq(PIC32MZ_IRQ_ETH);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mz_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* The network is locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void pic32mz_interrupt_work(void *arg)
|
||||
{
|
||||
struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
pic32mz_interrupt_process(priv);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts */
|
||||
|
||||
@@ -1906,7 +1862,6 @@ static void pic32mz_interrupt_work(void *arg)
|
||||
up_enable_irq(PIC32MZ_IRQ_ETH);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mz_interrupt
|
||||
@@ -1936,7 +1891,6 @@ static int pic32mz_interrupt(int irq, void *context)
|
||||
priv = &g_ethdrvr[0];
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. Because Ethernet interrupts are
|
||||
* also disabled if the TX timeout event occurs, there can be no race
|
||||
* condition here.
|
||||
@@ -1971,54 +1925,9 @@ static int pic32mz_interrupt(int irq, void *context)
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->pd_work, pic32mz_interrupt_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
pic32mz_interrupt_process(priv);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mz_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void pic32mz_txtimeout_process(struct pic32mz_driver_s *priv)
|
||||
{
|
||||
/* Increment statistics and dump debug info */
|
||||
|
||||
NETDEV_TXTIMEOUTS(&priv->pd_dev);
|
||||
if (priv->pd_ifup)
|
||||
{
|
||||
/* Then reset the hardware. ifup() will reset the interface, then bring
|
||||
* it back up.
|
||||
*/
|
||||
|
||||
(void)pic32mz_ifup(&priv->pd_dev);
|
||||
|
||||
/* Then poll the network for new XMIT data (We are guaranteed to have a free
|
||||
* buffer here).
|
||||
*/
|
||||
|
||||
pic32mz_poll(priv);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mz_txtimeout_work
|
||||
*
|
||||
@@ -2036,19 +1945,31 @@ static inline void pic32mz_txtimeout_process(struct pic32mz_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void pic32mz_txtimeout_work(void *arg)
|
||||
{
|
||||
struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
/* Increment statistics and dump debug info */
|
||||
|
||||
state = net_lock();
|
||||
pic32mz_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
NETDEV_TXTIMEOUTS(&priv->pd_dev);
|
||||
if (priv->pd_ifup)
|
||||
{
|
||||
/* Then reset the hardware. ifup() will reset the interface, then bring
|
||||
* it back up.
|
||||
*/
|
||||
|
||||
(void)pic32mz_ifup(&priv->pd_dev);
|
||||
|
||||
/* Then poll the network for new XMIT data (We are guaranteed to have a free
|
||||
* buffer here).
|
||||
*/
|
||||
|
||||
pic32mz_poll(priv);
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mz_txtimeout_expiry
|
||||
@@ -2073,7 +1994,6 @@ static void pic32mz_txtimeout_expiry(int argc, wdparm_t arg, ...)
|
||||
{
|
||||
struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -2094,50 +2014,6 @@ static void pic32mz_txtimeout_expiry(int argc, wdparm_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(ETHWORK, &priv->pd_work, pic32mz_txtimeout_work, priv, 0);
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
pic32mz_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mz_poll_process
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void pic32mz_poll_process(struct pic32mz_driver_s *priv)
|
||||
{
|
||||
/* Check if the next Tx descriptor is available. We cannot perform the Tx
|
||||
* poll if we are unable to accept another packet for transmission.
|
||||
*/
|
||||
|
||||
if (pic32mz_txdesc(priv) != NULL)
|
||||
{
|
||||
/* If so, update TCP timing states and poll the network for new XMIT
|
||||
* data. Hmmm.. might be bug here. Does this mean if there is a
|
||||
* transmit in progress, we will missing TCP time state updates?
|
||||
*/
|
||||
|
||||
pic32mz_timerpoll(priv);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->pd_txpoll, PIC32MZ_WDDELAY, pic32mz_poll_expiry,
|
||||
1, priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2157,19 +2033,31 @@ static inline void pic32mz_poll_process(struct pic32mz_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void pic32mz_poll_work(void *arg)
|
||||
{
|
||||
struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Check if the next Tx descriptor is available. We cannot perform the Tx
|
||||
* poll if we are unable to accept another packet for transmission.
|
||||
*/
|
||||
|
||||
state = net_lock();
|
||||
pic32mz_poll_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
if (pic32mz_txdesc(priv) != NULL)
|
||||
{
|
||||
/* If so, update TCP timing states and poll the network for new XMIT
|
||||
* data. Hmmm.. might be bug here. Does this mean if there is a
|
||||
* transmit in progress, we will missing TCP time state updates?
|
||||
*/
|
||||
|
||||
pic32mz_timerpoll(priv);
|
||||
}
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->pd_txpoll, PIC32MZ_WDDELAY, pic32mz_poll_expiry,
|
||||
1, priv);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mz_poll_expiry
|
||||
@@ -2193,7 +2081,6 @@ static void pic32mz_poll_expiry(int argc, wdparm_t arg, ...)
|
||||
{
|
||||
struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -2212,12 +2099,6 @@ static void pic32mz_poll_expiry(int argc, wdparm_t arg, ...)
|
||||
|
||||
(void)wd_start(priv->pd_txpoll, PIC32MZ_WDDELAY, pic32mz_poll_expiry, 1, arg);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
pic32mz_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -2573,42 +2454,6 @@ static int pic32mz_ifdown(struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mz_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void pic32mz_txavail_process(struct pic32mz_driver_s *priv)
|
||||
{
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
if (priv->pd_ifup)
|
||||
{
|
||||
/* Check if the next Tx descriptor is available. */
|
||||
|
||||
if (pic32mz_txdesc(priv) != NULL)
|
||||
{
|
||||
/* If so, then poll the network for new XMIT data. First allocate a buffer
|
||||
* to perform the poll
|
||||
*/
|
||||
|
||||
pic32mz_poll(priv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mz_txavail_work
|
||||
*
|
||||
@@ -2626,19 +2471,29 @@ static inline void pic32mz_txavail_process(struct pic32mz_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void pic32mz_txavail_work(void *arg)
|
||||
{
|
||||
struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
state = net_lock();
|
||||
pic32mz_txavail_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
if (priv->pd_ifup)
|
||||
{
|
||||
/* Check if the next Tx descriptor is available. */
|
||||
|
||||
if (pic32mz_txdesc(priv) != NULL)
|
||||
{
|
||||
/* If so, then poll the network for new XMIT data. First allocate a buffer
|
||||
* to perform the poll
|
||||
*/
|
||||
|
||||
pic32mz_poll(priv);
|
||||
}
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: pic32mz_txavail
|
||||
@@ -2663,7 +2518,6 @@ static int pic32mz_txavail(struct net_driver_s *dev)
|
||||
{
|
||||
struct pic32mz_driver_s *priv = (struct pic32mz_driver_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -2676,21 +2530,6 @@ static int pic32mz_txavail(struct net_driver_s *dev)
|
||||
work_queue(ETHWORK, &priv->pd_work, pic32mz_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
irqstate_t flags;
|
||||
|
||||
/* Disable interrupts because this function may be called from interrupt
|
||||
* level processing.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
pic32mz_txavail_process(priv);
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,20 +54,18 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/wdog.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/net/arp.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
#include <arch/board/generated/csr.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "hw/flags.h"
|
||||
#include "hw/ethmac_mem.h"
|
||||
#include "misoc.h"
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
# include <nuttx/wqueue.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_PKT
|
||||
# include <nuttx/net/pkt.h>
|
||||
#endif
|
||||
@@ -80,8 +78,8 @@
|
||||
* work queue support is required.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_NET_NOINTS) && !defined(CONFIG_SCHED_HPWORK)
|
||||
/* REVISIT: The low priority work queue would be preferred if it is avaiable */
|
||||
#if !defined(CONFIG_SCHED_HPWORK)
|
||||
/* REVISIT: The low priority work queue would be preferred if it is avaiable */
|
||||
|
||||
# error High priority work queue support is required
|
||||
#endif
|
||||
@@ -119,9 +117,7 @@ struct misoc_net_driver_s
|
||||
bool misoc_net_bifup; /* true:ifup false:ifdown */
|
||||
WDOG_ID misoc_net_txpoll; /* TX poll timer */
|
||||
WDOG_ID misoc_net_txtimeout; /* TX timeout timer */
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
struct work_s misoc_net_work; /* For deferring work to the work queue */
|
||||
#endif
|
||||
|
||||
uint8_t *rx0_buf; /* 2 RX and 2 TX buffer */
|
||||
uint8_t *rx1_buf;
|
||||
@@ -163,35 +159,26 @@ static int misoc_net_txpoll(FAR struct net_driver_s *dev);
|
||||
|
||||
static void misoc_net_receive(FAR struct misoc_net_driver_s *priv);
|
||||
static void misoc_net_txdone(FAR struct misoc_net_driver_s *priv);
|
||||
static inline void misoc_net_interrupt_process(FAR struct misoc_net_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void misoc_net_interrupt_work(FAR void *arg);
|
||||
#endif
|
||||
static int misoc_net_interrupt(int irq, FAR void *context);
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static inline void misoc_net_txtimeout_process(FAR struct misoc_net_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void misoc_net_txtimeout_work(FAR void *arg);
|
||||
#endif
|
||||
static void misoc_net_txtimeout_expiry(int argc, wdparm_t arg, ...);
|
||||
|
||||
static inline void misoc_net_poll_process(FAR struct misoc_net_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void misoc_net_poll_work(FAR void *arg);
|
||||
#endif
|
||||
static void misoc_net_poll_expiry(int argc, wdparm_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
|
||||
static int misoc_net_ifup(FAR struct net_driver_s *dev);
|
||||
static int misoc_net_ifdown(FAR struct net_driver_s *dev);
|
||||
static inline void misoc_net_txavail_process(FAR struct misoc_net_driver_s *priv);
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
|
||||
static void misoc_net_txavail_work(FAR void *arg);
|
||||
#endif
|
||||
static int misoc_net_txavail(FAR struct net_driver_s *dev);
|
||||
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
static int misoc_net_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac);
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
@@ -586,28 +573,29 @@ static void misoc_net_txdone(FAR struct misoc_net_driver_s *priv)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: misoc_net_interrupt_process
|
||||
* Function: misoc_net_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Interrupt processing. This may be performed either within the interrupt
|
||||
* handler or on the worker thread, depending upon the configuration
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* The network is locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void misoc_net_interrupt_process(FAR struct misoc_net_driver_s *priv)
|
||||
static void misoc_net_interrupt_work(FAR void *arg)
|
||||
{
|
||||
/* Get and clear interrupt status bits */
|
||||
FAR struct misoc_net_driver_s *priv = (FAR struct misoc_net_driver_s *)arg;
|
||||
|
||||
/* Handle interrupts according to status bit settings */
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
net_lock();
|
||||
|
||||
/* Check if we received an incoming packet, if so, call misoc_net_receive() */
|
||||
|
||||
@@ -626,42 +614,13 @@ static inline void misoc_net_interrupt_process(FAR struct misoc_net_driver_s *pr
|
||||
misoc_net_txdone(priv);
|
||||
ethmac_sram_reader_ev_pending_write(1);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: misoc_net_interrupt_work
|
||||
*
|
||||
* Description:
|
||||
* Perform interrupt related work from the worker thread
|
||||
*
|
||||
* Parameters:
|
||||
* arg - The argument passed when work_queue() was called.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
* The network is locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void misoc_net_interrupt_work(FAR void *arg)
|
||||
{
|
||||
FAR struct misoc_net_driver_s *priv = (FAR struct misoc_net_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
|
||||
state = net_lock();
|
||||
misoc_net_interrupt_process(priv);
|
||||
net_unlock(state);
|
||||
net_unlock();
|
||||
|
||||
/* Re-enable Ethernet interrupts */
|
||||
|
||||
up_enable_irq(ETHMAC_INTERRUPT);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: misoc_net_interrupt
|
||||
@@ -684,7 +643,6 @@ static int misoc_net_interrupt(int irq, FAR void *context)
|
||||
{
|
||||
FAR struct misoc_net_driver_s *priv = &g_misoc_net[0];
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. Because Ethernet interrupts are
|
||||
* also disabled if the TX timeout event occurs, there can be no race
|
||||
* condition here.
|
||||
@@ -709,47 +667,9 @@ static int misoc_net_interrupt(int irq, FAR void *context)
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
work_queue(HPWORK, &priv->misoc_net_work, misoc_net_interrupt_work, priv, 0);
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
misoc_net_interrupt_process(priv);
|
||||
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: misoc_net_txtimeout_process
|
||||
*
|
||||
* Description:
|
||||
* Process a TX timeout. Called from the either the watchdog timer
|
||||
* expiration logic or from the worker thread, depending upon the
|
||||
* configuration. The timeout means that the last TX never completed.
|
||||
* Reset the hardware and start again.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void misoc_net_txtimeout_process(FAR struct misoc_net_driver_s *priv)
|
||||
{
|
||||
/* Increment statistics and dump debug info */
|
||||
|
||||
NETDEV_TXTIMEOUTS(priv->misoc_net_dev);
|
||||
|
||||
/* Then reset the hardware */
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
(void)devif_poll(&priv->misoc_net_dev, misoc_net_txpoll);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: misoc_net_txtimeout_work
|
||||
*
|
||||
@@ -767,19 +687,22 @@ static inline void misoc_net_txtimeout_process(FAR struct misoc_net_driver_s *pr
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void misoc_net_txtimeout_work(FAR void *arg)
|
||||
{
|
||||
FAR struct misoc_net_driver_s *priv = (FAR struct misoc_net_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Process pending Ethernet interrupts */
|
||||
/* Increment statistics and dump debug info */
|
||||
|
||||
state = net_lock();
|
||||
misoc_net_txtimeout_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
NETDEV_TXTIMEOUTS(priv->misoc_net_dev);
|
||||
|
||||
/* Then reset the hardware */
|
||||
|
||||
/* Then poll the network for new XMIT data */
|
||||
|
||||
(void)devif_poll(&priv->misoc_net_dev, misoc_net_txpoll);
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: misoc_net_txtimeout_expiry
|
||||
@@ -804,7 +727,6 @@ static void misoc_net_txtimeout_expiry(int argc, wdparm_t arg, ...)
|
||||
{
|
||||
FAR struct misoc_net_driver_s *priv = (FAR struct misoc_net_driver_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
* condition with interrupt work that is already queued and in progress.
|
||||
@@ -821,47 +743,6 @@ static void misoc_net_txtimeout_expiry(int argc, wdparm_t arg, ...)
|
||||
/* Schedule to perform the TX timeout processing on the worker thread. */
|
||||
|
||||
work_queue(HPWORK, &priv->misoc_net_work, misoc_net_txtimeout_work, priv, 0);
|
||||
#else
|
||||
/* Process the timeout now */
|
||||
|
||||
misoc_net_txtimeout_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: misoc_net_poll_process
|
||||
*
|
||||
* Description:
|
||||
* Perform the periodic poll. This may be called either from watchdog
|
||||
* timer logic or from the worker thread, depending upon the configuration.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void misoc_net_poll_process(FAR struct misoc_net_driver_s *priv)
|
||||
{
|
||||
/* Check if there is room in the send another TX packet. We cannot perform
|
||||
* the TX poll if he are unable to accept another packet for transmission.
|
||||
*/
|
||||
|
||||
/* If so, update TCP timing states and poll the network for new XMIT data.
|
||||
* Hmmm.. might be bug here. Does this mean if there is a transmit in
|
||||
* progress, we will missing TCP time state updates?
|
||||
*/
|
||||
|
||||
(void)devif_timer(&priv->misoc_net_dev, misoc_net_txpoll);
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->misoc_net_txpoll, MISOC_NET_WDDELAY, misoc_net_poll_expiry, 1,
|
||||
(wdparm_t)priv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -881,19 +762,32 @@ static inline void misoc_net_poll_process(FAR struct misoc_net_driver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void misoc_net_poll_work(FAR void *arg)
|
||||
{
|
||||
FAR struct misoc_net_driver_s *priv = (FAR struct misoc_net_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
|
||||
state = net_lock();
|
||||
misoc_net_poll_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
|
||||
/* Check if there is room in the send another TX packet. We cannot perform
|
||||
* the TX poll if he are unable to accept another packet for transmission.
|
||||
*/
|
||||
|
||||
/* If so, update TCP timing states and poll the network for new XMIT data.
|
||||
* Hmmm.. might be bug here. Does this mean if there is a transmit in
|
||||
* progress, we will missing TCP time state updates?
|
||||
*/
|
||||
|
||||
(void)devif_timer(&priv->misoc_net_dev, misoc_net_txpoll);
|
||||
|
||||
/* Setup the watchdog poll timer again */
|
||||
|
||||
(void)wd_start(priv->misoc_net_txpoll, MISOC_NET_WDDELAY, misoc_net_poll_expiry, 1,
|
||||
(wdparm_t)priv);
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: misoc_net_poll_expiry
|
||||
@@ -917,7 +811,6 @@ static void misoc_net_poll_expiry(int argc, wdparm_t arg, ...)
|
||||
{
|
||||
FAR struct misoc_net_driver_s *priv = (FAR struct misoc_net_driver_s *)arg;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions.
|
||||
*/
|
||||
@@ -934,14 +827,9 @@ static void misoc_net_poll_expiry(int argc, wdparm_t arg, ...)
|
||||
* cycle.
|
||||
*/
|
||||
|
||||
(void)wd_start(priv->misoc_net_txpoll, MISOC_NET_WDDELAY, misoc_net_poll_expiry, 1, arg);
|
||||
(void)wd_start(priv->misoc_net_txpoll, MISOC_NET_WDDELAY,
|
||||
misoc_net_poll_expiry, 1, arg);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Process the interrupt now */
|
||||
|
||||
misoc_net_poll_process(priv);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -1044,40 +932,6 @@ static int misoc_net_ifdown(FAR struct net_driver_s *dev)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: misoc_net_txavail_process
|
||||
*
|
||||
* Description:
|
||||
* Perform an out-of-cycle poll.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - Reference to the NuttX driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called in normal user mode
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void misoc_net_txavail_process(FAR struct misoc_net_driver_s *priv)
|
||||
{
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
if (priv->misoc_net_bifup)
|
||||
{
|
||||
/* Check if there is room in the hardware to hold another outgoing packet. */
|
||||
|
||||
if (!ethmac_sram_reader_ready_read())
|
||||
{
|
||||
/* If so, then poll the network for new XMIT data */
|
||||
|
||||
(void)devif_poll(&priv->misoc_net_dev, misoc_net_txpoll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: misoc_net_txavail_work
|
||||
*
|
||||
@@ -1095,19 +949,27 @@ static inline void misoc_net_txavail_process(FAR struct misoc_net_driver_s *priv
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
static void misoc_net_txavail_work(FAR void *arg)
|
||||
{
|
||||
FAR struct misoc_net_driver_s *priv = (FAR struct misoc_net_driver_s *)arg;
|
||||
net_lock_t state;
|
||||
|
||||
/* Perform the poll */
|
||||
/* Ignore the notification if the interface is not yet up */
|
||||
|
||||
state = net_lock();
|
||||
misoc_net_txavail_process(priv);
|
||||
net_unlock(state);
|
||||
net_lock();
|
||||
if (priv->misoc_net_bifup)
|
||||
{
|
||||
/* Check if there is room in the hardware to hold another outgoing packet. */
|
||||
|
||||
if (!ethmac_sram_reader_ready_read())
|
||||
{
|
||||
/* If so, then poll the network for new XMIT data */
|
||||
|
||||
(void)devif_poll(&priv->misoc_net_dev, misoc_net_txpoll);
|
||||
}
|
||||
}
|
||||
|
||||
net_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: misoc_net_txavail
|
||||
@@ -1132,7 +994,6 @@ static int misoc_net_txavail(FAR struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct misoc_net_driver_s *priv = (FAR struct misoc_net_driver_s *)dev->d_private;
|
||||
|
||||
#ifdef CONFIG_NET_NOINTS
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
* availability action.
|
||||
@@ -1145,21 +1006,6 @@ static int misoc_net_txavail(FAR struct net_driver_s *dev)
|
||||
work_queue(HPWORK, &priv->misoc_net_work, misoc_net_txavail_work, priv, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
irqstate_t flags;
|
||||
|
||||
/* Disable interrupts because this function may be called from interrupt
|
||||
* level processing.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Perform the out-of-cycle poll now */
|
||||
|
||||
misoc_net_txavail_process(priv);
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
+77
-332
File diff suppressed because it is too large
Load Diff
@@ -477,7 +477,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -470,7 +470,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -478,7 +478,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -915,7 +915,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
CONFIG_ARCH_HAVE_PHY=y
|
||||
CONFIG_NET=y
|
||||
# CONFIG_NET_NOINTS is not set
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -226,7 +226,6 @@ Networking Support
|
||||
Networking Support
|
||||
CONFIG_NET=y : Enable Neworking
|
||||
CONFIG_NET_ETHERNET=y : Support Ethernet data link
|
||||
CONFIG_NET_NOINTS=y : Should operative at non-interrupt level
|
||||
CONFIG_NET_SOCKOPTS=y : Enable socket operations
|
||||
CONFIG_NET_ETH_MTU=590 : Maximum packet size (MTU) 1518 is more standard
|
||||
CONFIG_NET_ETH_TCP_RECVWNDO=536 : Should be the same as CONFIG_NET_ETH_MTU
|
||||
|
||||
@@ -676,7 +676,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -678,7 +678,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -609,7 +609,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -601,7 +601,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -643,7 +643,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -597,7 +597,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -632,7 +632,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -500,7 +500,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
CONFIG_ARCH_HAVE_PHY=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -509,7 +509,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
CONFIG_ARCH_HAVE_PHY=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -501,7 +501,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
CONFIG_ARCH_HAVE_PHY=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -512,7 +512,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
CONFIG_ARCH_HAVE_PHY=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -511,7 +511,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
CONFIG_ARCH_HAVE_PHY=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -971,7 +971,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -193,7 +193,6 @@ Networking Support
|
||||
Networking Support
|
||||
CONFIG_NET=y : Enable Neworking
|
||||
CONFIG_NET_ETHERNET=y : Support Ethernet data link
|
||||
CONFIG_NET_NOINTS=y : Should operative at non-interrupt level
|
||||
CONFIG_NET_SOCKOPTS=y : Enable socket operations
|
||||
CONFIG_NET_ETH_MTU=590 : Maximum packet size (MTU) 1518 is more standard
|
||||
CONFIG_NET_ETH_TCP_RECVWNDO=536 : Should be the same as CONFIG_NET_ETH_MTU
|
||||
|
||||
@@ -644,7 +644,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
CONFIG_ARCH_HAVE_PHY=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -623,7 +623,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
CONFIG_ARCH_HAVE_PHY=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -602,7 +602,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
CONFIG_ARCH_HAVE_PHY=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -623,7 +623,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -637,7 +637,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -637,7 +637,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -607,7 +607,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -647,7 +647,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -591,7 +591,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
CONFIG_ARCH_HAVE_PHY=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -663,7 +663,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
CONFIG_ARCH_HAVE_PHY=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -594,7 +594,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
CONFIG_ARCH_HAVE_PHY=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -481,7 +481,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
CONFIG_ARCH_HAVE_PHY=y
|
||||
CONFIG_NET=y
|
||||
# CONFIG_NET_NOINTS is not set
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -514,7 +514,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -509,7 +509,6 @@ CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_ARCH_HAVE_NET=y
|
||||
# CONFIG_ARCH_HAVE_PHY is not set
|
||||
CONFIG_NET=y
|
||||
CONFIG_NET_NOINTS=y
|
||||
# CONFIG_NET_PROMISCUOUS is not set
|
||||
|
||||
#
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user