diff options
author | John Crispin <john@openwrt.org> | 2013-06-10 08:25:17 +0000 |
---|---|---|
committer | John Crispin <john@openwrt.org> | 2013-06-10 08:25:17 +0000 |
commit | e40f830383cdcbd222e66919db0c08623af97dbb (patch) | |
tree | 038ab2c0a0cd5dbb26619947bfbc84e52bd1c514 /package | |
parent | 76c79f50d71f9ef08b67e85385344de9da70f53a (diff) | |
download | upstream-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
Diffstat (limited to 'package')
-rw-r--r-- | package/platform/lantiq/ltq-atm/src/ltq_atm.c | 22 |
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; } |