Skip to content

Commit

Permalink
Use small lock to protect resources related to ethernet.
Browse files Browse the repository at this point in the history
Signed-off-by: wangzhi16 <[email protected]>
  • Loading branch information
wangzhi-art authored and xiaoxiang781216 committed Jan 24, 2025
1 parent ace7f0c commit 6012503
Show file tree
Hide file tree
Showing 12 changed files with 100 additions and 61 deletions.
9 changes: 6 additions & 3 deletions arch/arm/src/c5471/c5471_ethernet.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
#include <net/ethernet.h>

#include <nuttx/wdog.h>
#include <nuttx/irq.h>
#include <nuttx/spinlock.h>
#include <nuttx/arch.h>
#include <nuttx/wqueue.h>
#include <nuttx/net/ip.h>
Expand Down Expand Up @@ -299,6 +299,7 @@ struct c5471_driver_s
struct wdog_s c_txtimeout; /* TX timeout timer */
struct work_s c_irqwork; /* For deferring interrupt work to the work queue */
struct work_s c_pollwork; /* For deferring poll work to the work queue */
spinlock_t c_lock; /* Spinlock */

/* Note: According to the C547x documentation: "The software has to
* maintain two pointers to the current RX-CPU and TX-CPU descriptors.
Expand Down Expand Up @@ -1786,7 +1787,7 @@ static int c5471_ifdown(struct net_driver_s *dev)

/* Disable the Ethernet interrupt */

flags = enter_critical_section();
flags = spin_lock_irqsave(&priv->c_lock);
up_disable_irq(C5471_IRQ_ETHER);

/* Disable interrupts going from EIM Module to Interrupt Module. */
Expand All @@ -1809,7 +1810,7 @@ static int c5471_ifdown(struct net_driver_s *dev)
/* Reset the device */

priv->c_bifup = false;
leave_critical_section(flags);
spin_unlock_irqrestore(&priv->c_lock, flags);
return OK;
}

Expand Down Expand Up @@ -2335,6 +2336,8 @@ void arm_netinitialize(void)
#endif
g_c5471[0].c_dev.d_private = g_c5471; /* Used to recover private state from dev */

spin_lock_init(&g_c5471[0].c_lock); /* Initialize spinlock */

/* Register the device with the OS so that socket IOCTLs can be performed */

netdev_register(&g_c5471[0].c_dev, NET_LL_ETHERNET);
Expand Down
34 changes: 20 additions & 14 deletions arch/arm/src/lpc17xx_40xx/lpc17_40_ethernet.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
#include <arpa/inet.h>

#include <nuttx/wdog.h>
#include <nuttx/irq.h>
#include <nuttx/spinlock.h>
#include <nuttx/arch.h>
#include <nuttx/wqueue.h>
#include <nuttx/signal.h>
Expand Down Expand Up @@ -298,6 +298,7 @@ struct lpc17_40_driver_s
struct work_s lp_rxwork; /* RX work continuation */
struct work_s lp_pollwork; /* Poll work continuation */
uint32_t status;
spinlock_t lp_lock; /* Spinlock */

/* This holds the information visible to the NuttX networking layer */

Expand Down Expand Up @@ -424,6 +425,7 @@ static inline void lpc17_40_txdescinit(struct lpc17_40_driver_s *priv);
static inline void lpc17_40_rxdescinit(struct lpc17_40_driver_s *priv);
static inline void lpc17_40_macmode(uint8_t mode);
static void lpc17_40_ethreset(struct lpc17_40_driver_s *priv);
static void lpc17_40_ethreset_nolock(struct lpc17_40_driver_s *priv);

/****************************************************************************
* Private Functions
Expand Down Expand Up @@ -1003,14 +1005,14 @@ static void lpc17_40_rxdone_work(void *arg)
* lp-txpending TX underrun state is in effect.
*/

flags = enter_critical_section();
flags = spin_lock_irqsave(&priv->lp_lock);
if (!priv->lp_txpending)
{
priv->lp_inten |= ETH_RXINTS;
lpc17_40_putreg(priv->lp_inten, LPC17_40_ETH_INTEN);
}

leave_critical_section(flags);
spin_unlock_irqrestore(&priv->lp_lock, flags);
}

/****************************************************************************
Expand Down Expand Up @@ -1534,7 +1536,7 @@ static int lpc17_40_ifdown(struct net_driver_s *dev)

/* Disable the Ethernet interrupt */

flags = enter_critical_section();
flags = spin_lock_irqsave(&priv->lp_lock);
up_disable_irq(LPC17_40_IRQ_ETH);

/* Cancel the TX timeout timers */
Expand All @@ -1543,9 +1545,9 @@ static int lpc17_40_ifdown(struct net_driver_s *dev)

/* Reset the device and mark it as down. */

lpc17_40_ethreset(priv);
lpc17_40_ethreset_nolock(priv);
priv->lp_ifup = false;
leave_critical_section(flags);
spin_unlock_irqrestore(&priv->lp_lock, flags);
return OK;
}

Expand Down Expand Up @@ -2909,14 +2911,8 @@ static inline void lpc17_40_macmode(uint8_t mode)
*
****************************************************************************/

static void lpc17_40_ethreset(struct lpc17_40_driver_s *priv)
static void lpc17_40_ethreset_nolock(struct lpc17_40_driver_s *priv)
{
irqstate_t flags;

/* Reset the MAC */

flags = enter_critical_section();

/* Put the MAC into the reset state */

lpc17_40_putreg((ETH_MAC1_TXRST | ETH_MAC1_MCSTXRST | ETH_MAC1_RXRST |
Expand Down Expand Up @@ -2965,7 +2961,15 @@ static void lpc17_40_ethreset(struct lpc17_40_driver_s *priv)
/* Clear any pending interrupts (shouldn't be any) */

lpc17_40_putreg(0xffffffff, LPC17_40_ETH_INTCLR);
leave_critical_section(flags);
}

static void lpc17_40_ethreset(struct lpc17_40_driver_s *priv)
{
irqstate_t flags;

flags = spin_lock_irqsave(&priv->lp_lock);
lpc17_40_ethreset_nolock(priv);
spin_unlock_irqrestore(&priv->lp_lock, flags);
}

/****************************************************************************
Expand Down Expand Up @@ -3033,6 +3037,8 @@ static inline int lpc17_40_ethinitialize(int intf)
#endif
priv->lp_dev.d_private = priv; /* Used to recover private state from dev */

spin_lock_init(&priv->lp_lock); /* Initialize spinlock */

#if CONFIG_LPC17_40_NINTERFACES > 1
# error "A mechanism to associate base address an IRQ with an interface is needed"
priv->lp_base = ??; /* Ethernet controller base address */
Expand Down
9 changes: 6 additions & 3 deletions arch/arm/src/lpc43xx/lpc43_ethernet.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#include <arpa/inet.h>

#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/spinlock.h>
#include <nuttx/queue.h>
#include <nuttx/wdog.h>
#include <nuttx/wqueue.h>
Expand Down Expand Up @@ -512,6 +512,7 @@ struct lpc43_ethmac_s
struct wdog_s txtimeout; /* TX timeout timer */
struct work_s irqwork; /* For deferring work to the work queue */
struct work_s pollwork; /* For deferring work to the work queue */
spinlock_t lock; /* Spinlock */

/* This holds the information visible to the NuttX network */

Expand Down Expand Up @@ -2126,7 +2127,7 @@ static int lpc43_ifdown(struct net_driver_s *dev)

/* Disable the Ethernet interrupt */

flags = enter_critical_section();
flags = spin_lock_irqsave(&priv->lock);
up_disable_irq(LPC43M4_IRQ_ETHERNET);

/* Cancel the TX timeout timers */
Expand All @@ -2143,7 +2144,7 @@ static int lpc43_ifdown(struct net_driver_s *dev)
/* Mark the device "down" */

priv->ifup = false;
leave_critical_section(flags);
spin_unlock_irqrestore(&priv->lock, flags);
return OK;
}

Expand Down Expand Up @@ -3607,6 +3608,8 @@ static inline int lpc43_ethinitialize(void)
#endif
priv->dev.d_private = &g_lpc43ethmac; /* Used to recover private state from dev */

spin_lock_init(&priv->lock); /* Initialize spinlock */

/* Configure GPIO pins to support Ethernet */

lpc43_ethgpioconfig(priv);
Expand Down
13 changes: 8 additions & 5 deletions arch/arm/src/lpc54xx/lpc54_ethernet.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
#include <arpa/inet.h>

#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/spinlock.h>
#include <nuttx/queue.h>
#include <nuttx/wdog.h>
#include <nuttx/wqueue.h>
Expand Down Expand Up @@ -297,6 +297,7 @@ struct lpc54_ethdriver_s
struct work_s eth_pollwork; /* For deferring poll work to the work queue */
struct work_s eth_timeoutwork; /* For deferring timeout work to the work queue */
struct sq_queue_s eth_freebuf; /* Free packet buffers */
spinlock_t lock; /* Spinlock */

/* Ring state */

Expand Down Expand Up @@ -1450,7 +1451,7 @@ static void lpc54_eth_interrupt_work(void *arg)
lpc54_eth_channel_work(priv, 1);
}

/* Un-lock the network and re-enable Ethernet interrupts */
/* Un-eth_lock the network and re-enable Ethernet interrupts */

net_unlock();
up_enable_irq(LPC54_IRQ_ETHERNET);
Expand Down Expand Up @@ -2001,7 +2002,7 @@ static int lpc54_eth_ifdown(struct net_driver_s *dev)

/* Disable the Ethernet interrupt */

flags = enter_critical_section();
flags = spin_lock_irqsave(&priv->eth_lock);
up_disable_irq(LPC54_IRQ_ETHERNET);

/* Cancel the TX timeout timers */
Expand Down Expand Up @@ -2040,14 +2041,14 @@ static int lpc54_eth_ifdown(struct net_driver_s *dev)
if (ret < 0)
{
nerr("ERROR: lpc54_phy_reset failed: %d\n", ret);
leave_critical_section(flags);
spin_unlock_irqrestore(&priv->eth_lock, flags);
return ret;
}

/* Mark the device "down" */

priv->eth_bifup = 0;
leave_critical_section(flags);
spin_unlock_irqrestore(&priv->eth_lock, flags);
return OK;
}

Expand Down Expand Up @@ -2881,6 +2882,8 @@ void arm_netinitialize(void)
#endif
priv->eth_dev.d_private = &g_ethdriver; /* Used to recover private state from dev */

spin_lock_init(&priv->eth_lock); /* Initialize spinlock */

/* Configure GPIO pins to support Ethernet */

/* Common MIIM interface */
Expand Down
9 changes: 6 additions & 3 deletions arch/arm/src/stm32f7/stm32_ethernet.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
#include <arpa/inet.h>

#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/spinlock.h>
#include <nuttx/queue.h>
#include <nuttx/wdog.h>
#include <nuttx/wqueue.h>
Expand Down Expand Up @@ -614,6 +614,7 @@ struct stm32_ethmac_s
struct wdog_s txtimeout; /* TX timeout timer */
struct work_s irqwork; /* For deferring interrupt work to the work queue */
struct work_s pollwork; /* For deferring poll work to the work queue */
spinlock_t lock; /* Spinlock */

/* This holds the information visible to the NuttX network */

Expand Down Expand Up @@ -2359,7 +2360,7 @@ static int stm32_ifdown(struct net_driver_s *dev)

/* Disable the Ethernet interrupt */

flags = enter_critical_section();
flags = spin_lock_irqsave(&priv->lock);
up_disable_irq(STM32_IRQ_ETH);

/* Cancel the TX timeout timers */
Expand All @@ -2376,7 +2377,7 @@ static int stm32_ifdown(struct net_driver_s *dev)
/* Mark the device "down" */

priv->ifup = false;
leave_critical_section(flags);
spin_unlock_irqrestore(&priv->lock, flags);
return OK;
}

Expand Down Expand Up @@ -3931,6 +3932,8 @@ int stm32_ethinitialize(int intf)
priv->dev.d_private = g_stm32ethmac; /* Used to recover private state from dev */
priv->intf = intf; /* Remember the interface number */

spin_lock_init(&priv->lock); /* Initialize spinlock */

stm32_get_uniqueid(uid);
crc = crc64(uid, 12);

Expand Down
9 changes: 6 additions & 3 deletions arch/arm/src/stm32h5/stm32_ethernet.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
#include <arpa/inet.h>

#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/spinlock.h>
#include <nuttx/queue.h>
#include <nuttx/wdog.h>
#include <nuttx/wqueue.h>
Expand Down Expand Up @@ -613,6 +613,7 @@ struct stm32_ethmac_s
struct wdog_s txtimeout; /* TX timeout timer */
struct work_s irqwork; /* For deferring interrupt work to the work queue */
struct work_s pollwork; /* For deferring poll work to the work queue */
spinlock_t lock; /* Spinlock */

/* This holds the information visible to the NuttX network */

Expand Down Expand Up @@ -2472,7 +2473,7 @@ static int stm32_ifdown(struct net_driver_s *dev)

/* Disable the Ethernet interrupt */

flags = enter_critical_section();
flags = spin_lock_irqsave(&priv->lock);
up_disable_irq(STM32_IRQ_ETH);

/* Cancel the TX timeout timers */
Expand All @@ -2489,7 +2490,7 @@ static int stm32_ifdown(struct net_driver_s *dev)
/* Mark the device "down" */

priv->ifup = false;
leave_critical_section(flags);
spin_unlock_irqrestore(&priv->lock, flags);
return OK;
}

Expand Down Expand Up @@ -4192,6 +4193,8 @@ static inline int stm32_ethinitialize(int intf)
priv->dev.d_private = g_stm32ethmac; /* Used to recover private state */
priv->intf = intf; /* Remember the interface number */

spin_lock_init(&priv->lock); /* Initialize spinlock */

stm32_get_uniqueid(uid);
crc = crc64(uid, 12);

Expand Down
9 changes: 6 additions & 3 deletions arch/arm/src/stm32h7/stm32_ethernet.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
#include <arpa/inet.h>

#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <nuttx/spinlock.h>
#include <nuttx/queue.h>
#include <nuttx/wdog.h>
#include <nuttx/wqueue.h>
Expand Down Expand Up @@ -614,6 +614,7 @@ struct stm32_ethmac_s
struct wdog_s txtimeout; /* TX timeout timer */
struct work_s irqwork; /* For deferring interrupt work to the work queue */
struct work_s pollwork; /* For deferring poll work to the work queue */
spinlock_t lock; /* Spinlock */

/* This holds the information visible to the NuttX network */

Expand Down Expand Up @@ -2473,7 +2474,7 @@ static int stm32_ifdown(struct net_driver_s *dev)

/* Disable the Ethernet interrupt */

flags = enter_critical_section();
flags = spin_lock_irqsave(&priv->lock);
up_disable_irq(STM32_IRQ_ETH);

/* Cancel the TX timeout timers */
Expand All @@ -2490,7 +2491,7 @@ static int stm32_ifdown(struct net_driver_s *dev)
/* Mark the device "down" */

priv->ifup = false;
leave_critical_section(flags);
spin_unlock_irqrestore(&priv->lock, flags);
return OK;
}

Expand Down Expand Up @@ -4191,6 +4192,8 @@ static inline int stm32_ethinitialize(int intf)
priv->dev.d_private = g_stm32ethmac; /* Used to recover private state */
priv->intf = intf; /* Remember the interface number */

spin_lock_init(&priv->lock); /* Initialize spinlock */

stm32_get_uniqueid(uid);
crc = crc64(uid, 12);

Expand Down
Loading

0 comments on commit 6012503

Please sign in to comment.