All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] mrf24j40: Avoid transmission while receiving a frame
@ 2013-05-09 15:19 ` David Hauweele
  0 siblings, 0 replies; 37+ messages in thread
From: David Hauweele @ 2013-05-09 15:19 UTC (permalink / raw)
  To: Alexander Smirnov, Dmitry Eremin-Solenikov, linux-zigbee-devel
  Cc: netdev, linux-kernel, David Hauweele

The transceiver may fail under heavy traffic when a frame is transmitted
while receiving another frame.

This patch uses a mutex to separate the transmission and reception of
frames along with a secondary working queue to avoid a deadlock while
waiting for the transmission interrupt.

Signed-off-by: David Hauweele <david@hauweele.net>
---
 drivers/net/ieee802154/mrf24j40.c |   22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c
index ede3ce4..1e3ddf3 100644
--- a/drivers/net/ieee802154/mrf24j40.c
+++ b/drivers/net/ieee802154/mrf24j40.c
@@ -82,8 +82,10 @@ struct mrf24j40 {
 	struct ieee802154_dev *dev;
 
 	struct mutex buffer_mutex; /* only used to protect buf */
+	struct mutex txrx_mutex; /* avoid transmission while receiving a frame */
 	struct completion tx_complete;
 	struct work_struct irqwork;
+	struct work_struct rxwork;
 	u8 *buf; /* 3 bytes. Used for SPI single-register transfers. */
 };
 
@@ -353,6 +355,8 @@ static int mrf24j40_tx(struct ieee802154_dev *dev, struct sk_buff *skb)
 	/* Set TXNACKREQ if the ACK bit is set in the packet. */
 	if (skb->data[0] & IEEE802154_FC_ACK_REQ)
 		val |= 0x4;
+
+	mutex_lock(&devrec->txrx_mutex);
 	write_short_reg(devrec, REG_TXNCON, val);
 
 	INIT_COMPLETION(devrec->tx_complete);
@@ -361,6 +365,9 @@ static int mrf24j40_tx(struct ieee802154_dev *dev, struct sk_buff *skb)
 	ret = wait_for_completion_interruptible_timeout(
 						&devrec->tx_complete,
 						5 * HZ);
+
+	mutex_unlock(&devrec->txrx_mutex);
+
 	if (ret == -ERESTARTSYS)
 		goto err;
 	if (ret == 0) {
@@ -535,6 +542,8 @@ static int mrf24j40_handle_rx(struct mrf24j40 *devrec)
 	int ret = 0;
 	struct sk_buff *skb;
 
+	mutex_lock(&devrec->txrx_mutex);
+
 	/* Turn off reception of packets off the air. This prevents the
 	 * device from overwriting the buffer while we're reading it. */
 	ret = read_short_reg(devrec, REG_BBREG1, &val);
@@ -575,6 +584,8 @@ out:
 	val &= ~0x4; /* Clear RXDECINV */
 	write_short_reg(devrec, REG_BBREG1, val);
 
+	mutex_unlock(&devrec->txrx_mutex);
+
 	return ret;
 }
 
@@ -616,12 +627,19 @@ static void mrf24j40_isrwork(struct work_struct *work)
 
 	/* Check for Rx */
 	if (intstat & 0x8)
-		mrf24j40_handle_rx(devrec);
+		schedule_work(&devrec->rxwork);
 
 out:
 	enable_irq(devrec->spi->irq);
 }
 
+static void mrf24j40_rxwork(struct work_struct *work)
+{
+	struct mrf24j40 *devrec = container_of(work, struct mrf24j40, rxwork);
+
+	mrf24j40_handle_rx(devrec);
+}
+
 static int mrf24j40_probe(struct spi_device *spi)
 {
 	int ret = -ENOMEM;
@@ -648,8 +666,10 @@ static int mrf24j40_probe(struct spi_device *spi)
 		spi->max_speed_hz = MAX_SPI_SPEED_HZ;
 
 	mutex_init(&devrec->buffer_mutex);
+	mutex_init(&devrec->txrx_mutex);
 	init_completion(&devrec->tx_complete);
 	INIT_WORK(&devrec->irqwork, mrf24j40_isrwork);
+	INIT_WORK(&devrec->rxwork, mrf24j40_rxwork);
 	devrec->spi = spi;
 	spi_set_drvdata(spi, devrec);
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2013-10-08 19:32 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-05-09 15:19 [PATCH 1/2] mrf24j40: Avoid transmission while receiving a frame David Hauweele
2013-05-09 15:19 ` David Hauweele
2013-05-09 15:19 ` [PATCH 2/2] mrf24j40: Keep the interrupt line enabled David Hauweele
2013-05-14  3:55   ` [Linux-zigbee-devel] " Alan Ott
2013-05-14  3:55     ` Alan Ott
2013-05-16 21:34     ` [Linux-zigbee-devel] " David Hauweele
2013-05-19 23:04       ` Alan Ott
2013-05-21 16:17         ` David Hauweele
2013-05-21 18:22           ` Alan Ott
2013-05-21 18:22             ` Alan Ott
2013-05-14  3:22 ` [Linux-zigbee-devel] [PATCH 1/2] mrf24j40: Avoid transmission while receiving a frame Alan Ott
     [not found]   ` <5191ADE4.8040709-yzvJWuRpmD1zbRFIqnYvSA@public.gmane.org>
2013-05-16 17:45     ` David Hauweele
2013-05-20  0:05       ` [PATCH testing] mrf24j40: Move INIT_COMPLETION to before the packet is sent Alan Ott
2013-05-20  0:05         ` Alan Ott
2013-05-22  2:01       ` [PATCH beta 1] 0/3] Fix race conditions in mrf24j40 interrupts Alan Ott
2013-05-22  2:01         ` Alan Ott
2013-05-22  2:01         ` [PATCH beta 1] 1/3] mrf24j40: Move INIT_COMPLETION() to before packet transmission Alan Ott
2013-05-22  2:01           ` Alan Ott
2013-05-22  2:01         ` [PATCH beta 1] 2/3] mrf24j40: Use threaded IRQ handler Alan Ott
2013-05-22  2:01           ` Alan Ott
2013-05-22  2:01         ` [PATCH beta 1] 3/3] mrf24j40: Use level-triggered interrupts Alan Ott
2013-05-22  2:03         ` [PATCH beta 1] 0/3] Fix race conditions in mrf24j40 interrupts Alan Ott
2013-05-22 20:32           ` David Hauweele
2013-05-23  6:36             ` Alan Ott
2013-05-23  6:36               ` Alan Ott
2013-05-23 17:54               ` David Hauweele
2013-05-23 17:54                 ` David Hauweele
2013-05-23 19:33                 ` Alan Ott
2013-10-06  3:52         ` [PATCH v1 " Alan Ott
2013-10-06  3:52           ` Alan Ott
2013-10-06  3:52           ` [PATCH v1 1/3] mrf24j40: Move INIT_COMPLETION() to before packet transmission Alan Ott
2013-10-06  3:52             ` Alan Ott
2013-10-06  3:52           ` [PATCH v1 2/3] mrf24j40: Use threaded IRQ handler Alan Ott
2013-10-06  3:52             ` Alan Ott
2013-10-06  3:52           ` [PATCH v1 3/3] mrf24j40: Use level-triggered interrupts Alan Ott
2013-10-06  3:52             ` Alan Ott
2013-10-08 19:32           ` [PATCH v1 0/3] Fix race conditions in mrf24j40 interrupts David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.