diff options
-rw-r--r-- | nuttx/arch/arm/src/tiva/tm4c_ethernet.c | 98 | ||||
-rw-r--r-- | nuttx/drivers/net/skeleton.c | 104 |
2 files changed, 176 insertions, 26 deletions
diff --git a/nuttx/arch/arm/src/tiva/tm4c_ethernet.c b/nuttx/arch/arm/src/tiva/tm4c_ethernet.c index 8ef82c0e1..98efdb2ea 100644 --- a/nuttx/arch/arm/src/tiva/tm4c_ethernet.c +++ b/nuttx/arch/arm/src/tiva/tm4c_ethernet.c @@ -726,6 +726,10 @@ 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(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); #ifdef CONFIG_NET_IGMP static int tiva_addmac(struct net_driver_s *dev, FAR const uint8_t *mac); @@ -1820,7 +1824,7 @@ static void tiva_receive(FAR struct tiva_ethmac_s *priv) static void tiva_freeframe(FAR struct tiva_ethmac_s *priv) { - struct emac_txdesc_s *txdesc; + FAR struct emac_txdesc_s *txdesc; int i; nvdbg("txhead: %p txtail: %p inflight: %d\n", @@ -1916,11 +1920,15 @@ static void tiva_freeframe(FAR struct tiva_ethmac_s *priv) static void tiva_txdone(FAR struct tiva_ethmac_s *priv) { + FAR struct net_driver_s *dev = &priv->dev; + DEBUGASSERT(priv->txtail != NULL); /* Scan the TX descriptor change, returning buffers to free list */ tiva_freeframe(priv); + dev->d_buf = NULL; + dev->d_len = 0; /* If no further xmits are pending, then cancel the TX timeout */ @@ -2502,6 +2510,65 @@ static int tiva_ifdown(struct net_driver_s *dev) } /**************************************************************************** + * 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) +{ + nvdbg("ifup: %d\n", priv->ifup); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->ifup) + { + /* Poll uIP for new XMIT data */ + + tiva_dopoll(priv); + } +} + +/**************************************************************************** + * Function: tiva_txavail_work + * + * Description: + * Perform an out-of-cycle poll on the worker thread. + * + * Parameters: + * arg - Reference to the NuttX driver state structure (cast to void*) + * + * Returned Value: + * None + * + * Assumptions: + * Called on the higher priority worker thread. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void tiva_txavail_work(FAR void *arg) +{ + FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)arg; + + /* Perform the poll */ + + tiva_txavail_process(priv); +} +#endif + +/**************************************************************************** * Function: tiva_txavail * * Description: @@ -2523,9 +2590,22 @@ static int tiva_ifdown(struct net_driver_s *dev) static int tiva_txavail(struct net_driver_s *dev) { FAR struct tiva_ethmac_s *priv = (FAR struct tiva_ethmac_s *)dev->d_private; - irqstate_t flags; - nvdbg("ifup: %d\n", priv->ifup); +#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. + */ + + if (work_available(&priv->work)) + { + /* Schedule to serialize the poll on the worker thread. */ + + work_queue(HPWORK, &priv->work, tiva_txavail_work, priv, 0); + } + +#else + irqstate_t flags; /* Disable interrupts because this function may be called from interrupt * level processing. @@ -2533,16 +2613,12 @@ static int tiva_txavail(struct net_driver_s *dev) flags = irqsave(); - /* Ignore the notification if the interface is not yet up */ - - if (priv->ifup) - { - /* Poll uIP for new XMIT data */ - - tiva_dopoll(priv); - } + /* Perform the out-of-cycle poll now */ + tiva_txavail_process(priv); irqrestore(flags); +#endif + return OK; } diff --git a/nuttx/drivers/net/skeleton.c b/nuttx/drivers/net/skeleton.c index 1a932c056..86f1f83a1 100644 --- a/nuttx/drivers/net/skeleton.c +++ b/nuttx/drivers/net/skeleton.c @@ -155,12 +155,16 @@ static void skel_poll_expiry(int argc, uint32_t arg, ...); /* NuttX callback functions */ -static int skel_ifup(struct net_driver_s *dev); -static int skel_ifdown(struct net_driver_s *dev); -static int skel_txavail(struct net_driver_s *dev); +static int skel_ifup(FAR struct net_driver_s *dev); +static int skel_ifdown(FAR struct net_driver_s *dev); +static inline int skel_txavail_process(FAR struct skel_driver_s *skel); +#ifdef CONFIG_NET_NOINTS +static void skel_txavail_work(FAR void *arg); +#endif +static int skel_txavail(FAR struct net_driver_s *dev); #ifdef CONFIG_NET_IGMP -static int skel_addmac(struct net_driver_s *dev, FAR const uint8_t *mac); -static int skel_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac); +static int skel_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac); +static int skel_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac); #endif /**************************************************************************** @@ -827,6 +831,67 @@ static int skel_ifdown(struct net_driver_s *dev) } /**************************************************************************** + * Function: skel_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 int inline skel_txavail_process(FAR struct skel_driver_s *skel) +{ + /* Ignore the notification if the interface is not yet up */ + + if (skel->sk_bifup) + { + /* Check if there is room in the hardware to hold another outgoing packet. */ + + /* If so, then poll uIP for new XMIT data */ + + (void)devif_poll(&skel->sk_dev, skel_txpoll); + } + + return OK; +} + +/**************************************************************************** + * Function: skel_txavail_work + * + * Description: + * Perform an out-of-cycle poll on the worker thread. + * + * Parameters: + * arg - Reference to the NuttX driver state structure (cast to void*) + * + * Returned Value: + * None + * + * Assumptions: + * Called on the higher priority worker thread. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_NOINTS +static void skel_txavail_work(FAR void *arg) +{ + FAR struct skel_driver_s *skel = (FAR struct skel_driver_s *)arg; + + /* Perform the poll */ + + skel_txavail_process(skel); +} +#endif + +/**************************************************************************** * Function: skel_txavail * * Description: @@ -848,6 +913,21 @@ static int skel_ifdown(struct net_driver_s *dev) static int skel_txavail(struct net_driver_s *dev) { FAR struct skel_driver_s *skel = (FAR struct skel_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. + */ + + if (work_available(&skel->sk_work)) + { + /* Schedule to serialize the poll on the worker thread. */ + + work_queue(HPWORK, &skel->sk_work, skel_txavail_work, skel, 0); + } + +#else irqstate_t flags; /* Disable interrupts because this function may be called from interrupt @@ -856,18 +936,12 @@ static int skel_txavail(struct net_driver_s *dev) flags = irqsave(); - /* Ignore the notification if the interface is not yet up */ - - if (skel->sk_bifup) - { - /* Check if there is room in the hardware to hold another outgoing packet. */ - - /* If so, then poll uIP for new XMIT data */ - - (void)devif_poll(&skel->sk_dev, skel_txpoll); - } + /* Perform the out-of-cycle poll now */ + skel_poll_process(skel); irqrestore(flags); +#endif + return OK; } |