aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Crispin <john@openwrt.org>2013-06-10 08:25:17 +0000
committerJohn Crispin <john@openwrt.org>2013-06-10 08:25:17 +0000
commite40f830383cdcbd222e66919db0c08623af97dbb (patch)
tree038ab2c0a0cd5dbb26619947bfbc84e52bd1c514
parent76c79f50d71f9ef08b67e85385344de9da70f53a (diff)
downloadupstream-e40f830383cdcbd222e66919db0c08623af97dbb.tar.gz
upstream-e40f830383cdcbd222e66919db0c08623af97dbb.tar.bz2
upstream-e40f830383cdcbd222e66919db0c08623af97dbb.zip
lantiq: atm: Use a tasklet to handle incoming packets. Fix #12917.
Incoming packets are now processes in a tasklet instead of in the irq handler; this should improve latency. This patch is based on a previous version of ltq-atm driver, which did implement a tasklet. It has been tested on a arv4518pw with a Lantiq Danube for about a month and it seems to work well. Signed-off-by: Luca Dariz <luca.dariz@gmail.com> Tested-by: Luca Dariz <luca.dariz@gmail.com> SVN-Revision: 36902
-rw-r--r--package/platform/lantiq/ltq-atm/src/ltq_atm.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/package/platform/lantiq/ltq-atm/src/ltq_atm.c b/package/platform/lantiq/ltq-atm/src/ltq_atm.c
index 0e7e6e915f..8466510c6b 100644
--- a/package/platform/lantiq/ltq-atm/src/ltq_atm.c
+++ b/package/platform/lantiq/ltq-atm/src/ltq_atm.c
@@ -199,6 +199,8 @@ static inline void mailbox_oam_rx_handler(void);
static inline void mailbox_aal_rx_handler(void);
static irqreturn_t mailbox_irq_handler(int, void *);
static inline void mailbox_signal(unsigned int, int);
+static void do_ppe_tasklet(unsigned long);
+DECLARE_TASKLET(g_dma_tasklet, do_ppe_tasklet, 0);
/*
* QSB & HTU setting functions
@@ -491,6 +493,9 @@ static void ppe_close(struct atm_vcc *vcc)
break;
}
+ /* wait for incoming packets to be processed by upper layers */
+ tasklet_unlock_wait(&g_dma_tasklet);
+
PPE_CLOSE_EXIT:
return;
}
@@ -1039,14 +1044,25 @@ static inline void mailbox_aal_rx_handler(void)
}
}
+static void do_ppe_tasklet(unsigned long data)
+{
+ *MBOX_IGU1_ISRC = *MBOX_IGU1_ISR;
+ mailbox_oam_rx_handler();
+ mailbox_aal_rx_handler();
+
+ if ((*MBOX_IGU1_ISR & ((1 << RX_DMA_CH_AAL) | (1 << RX_DMA_CH_OAM))) != 0)
+ tasklet_schedule(&g_dma_tasklet);
+ else
+ enable_irq(PPE_MAILBOX_IGU1_INT);
+}
+
static irqreturn_t mailbox_irq_handler(int irq, void *dev_id)
{
if ( !*MBOX_IGU1_ISR )
return IRQ_HANDLED;
- *MBOX_IGU1_ISRC = *MBOX_IGU1_ISR;
- mailbox_oam_rx_handler();
- mailbox_aal_rx_handler();
+ disable_irq_nosync(PPE_MAILBOX_IGU1_INT);
+ tasklet_schedule(&g_dma_tasklet);
return IRQ_HANDLED;
}