diff options
Diffstat (limited to 'package/ifxmips-atm/src/irq.c')
-rw-r--r-- | package/ifxmips-atm/src/irq.c | 506 |
1 files changed, 0 insertions, 506 deletions
diff --git a/package/ifxmips-atm/src/irq.c b/package/ifxmips-atm/src/irq.c deleted file mode 100644 index 02651686b9..0000000000 --- a/package/ifxmips-atm/src/irq.c +++ /dev/null @@ -1,506 +0,0 @@ -#include <linux/atmdev.h> -#include <linux/irq.h> - -#include "common.h" - -void mailbox_signal(unsigned int channel, int is_tx) -{ - if(is_tx) - { - while(MBOX_IGU3_ISR_ISR(channel + 16)); - *MBOX_IGU3_ISRS = MBOX_IGU3_ISRS_SET(channel + 16); - } else { - while(MBOX_IGU3_ISR_ISR(channel)); - *MBOX_IGU3_ISRS = MBOX_IGU3_ISRS_SET(channel); - } -} - -static int mailbox_rx_irq_handler(unsigned int channel, unsigned int *len) -{ - int conn; - int skb_base; - register struct rx_descriptor reg_desc; - struct rx_descriptor *desc; - struct sk_buff *skb; - struct atm_vcc *vcc; - struct rx_inband_trailer *trailer; - - /* get sk_buff pointer and descriptor */ - skb_base = ppe_dev.dma.rx_descriptor_number * channel + ppe_dev.dma.rx_desc_read_pos[channel]; - desc = &ppe_dev.dma.rx_descriptor_base[skb_base]; - reg_desc = *desc; - if ( reg_desc.own || !reg_desc.c ) - return -EAGAIN; - - if ( ++ppe_dev.dma.rx_desc_read_pos[channel] == ppe_dev.dma.rx_descriptor_number ) - ppe_dev.dma.rx_desc_read_pos[channel] = 0; - - skb = *(struct sk_buff **)((((u32)reg_desc.dataptr << 2) | KSEG0) - 4); - if ( (u32)skb <= 0x80000000 ) - { - int key = 0; - printk("skb problem: skb = %08X, system is panic!\n", (u32)skb); - for ( ; !key; ); - } - - conn = reg_desc.id; - - if ( conn == ppe_dev.oam_rx_queue ) - { - /* OAM */ - struct uni_cell_header *header = (struct uni_cell_header *)skb->data; - - if ( header->pti == ATM_PTI_SEGF5 || header->pti == ATM_PTI_E2EF5 ) - conn = find_vpivci(header->vpi, header->vci); - else if ( header->vci == 0x03 || header->vci == 0x04 ) - conn = find_vpi(header->vpi); - else - conn = -1; - - if ( conn >= 0 && ppe_dev.connection[conn].vcc != NULL ) - { - vcc = ppe_dev.connection[conn].vcc; - ppe_dev.connection[conn].access_time = xtime; - if ( vcc->push_oam != NULL ) - vcc->push_oam(vcc, skb->data); - } - - /* don't need resize */ - } - else - { - if ( len ) - *len = 0; - - if ( ppe_dev.connection[conn].vcc != NULL ) - { - vcc = ppe_dev.connection[conn].vcc; - - if ( !reg_desc.err ) - if ( vcc->qos.aal == ATM_AAL5 ) - { - /* AAL5 packet */ - resize_skb_rx(skb, reg_desc.datalen + reg_desc.byteoff, 0); - skb_reserve(skb, reg_desc.byteoff); - skb_put(skb, reg_desc.datalen); - - if ( (u32)ATM_SKB(skb) <= 0x80000000 ) - { - int key = 0; - printk("ATM_SKB(skb) problem: ATM_SKB(skb) = %08X, system is panic!\n", (u32)ATM_SKB(skb)); - for ( ; !key; ); - } - ATM_SKB(skb)->vcc = vcc; - ppe_dev.connection[conn].access_time = xtime; - if ( atm_charge(vcc, skb->truesize) ) - { - struct sk_buff *new_skb; - - new_skb = alloc_skb_rx(); - if ( new_skb ) - { - - UPDATE_VCC_STAT(conn, rx_pdu, 1); - - ppe_dev.mib.wrx_pdu++; - if ( vcc->stats ) - atomic_inc(&vcc->stats->rx); - vcc->push(vcc, skb); - { - struct k_atm_aal_stats stats = *vcc->stats; - int flag = 0; - - vcc->push(vcc, skb); - if ( vcc->stats->rx.counter != stats.rx.counter ) - { - printk("vcc->stats->rx (diff) = %d", vcc->stats->rx.counter - stats.rx.counter); - flag++; - } - if ( vcc->stats->rx_err.counter != stats.rx_err.counter ) - { - printk("vcc->stats->rx_err (diff) = %d", vcc->stats->rx_err.counter - stats.rx_err.counter); - flag++; - } - if ( vcc->stats->rx_drop.counter != stats.rx_drop.counter ) - { - printk("vcc->stats->rx_drop (diff) = %d", vcc->stats->rx_drop.counter - stats.rx_drop.counter); - flag++; - } - if ( vcc->stats->tx.counter != stats.tx.counter ) - { - printk("vcc->stats->tx (diff) = %d", vcc->stats->tx.counter - stats.tx.counter); - flag++; - } - if ( vcc->stats->tx_err.counter != stats.tx_err.counter ) - { - printk("vcc->stats->tx_err (diff) = %d", vcc->stats->tx_err.counter - stats.tx_err.counter); - flag++; - } - if ( !flag ) - printk("vcc->stats not changed"); - } - reg_desc.dataptr = (u32)new_skb->data >> 2; - - if ( len ) - *len = reg_desc.datalen; - } - else - { - /* no sk buffer */ - UPDATE_VCC_STAT(conn, rx_sw_drop_pdu, 1); - - ppe_dev.mib.wrx_drop_pdu++; - if ( vcc->stats ) - atomic_inc(&vcc->stats->rx_drop); - - resize_skb_rx(skb, ppe_dev.aal5.rx_buffer_size, 0); - } - } - else - { - /* no enough space */ - UPDATE_VCC_STAT(conn, rx_sw_drop_pdu, 1); - - ppe_dev.mib.wrx_drop_pdu++; - if ( vcc->stats ) - atomic_inc(&vcc->stats->rx_drop); - - resize_skb_rx(skb, ppe_dev.aal5.rx_buffer_size, 0); - } - } - else - { - /* AAL0 cell */ - resize_skb_rx(skb, CELL_SIZE, 1); - skb_put(skb, CELL_SIZE); - - ATM_SKB(skb)->vcc = vcc; - ppe_dev.connection[conn].access_time = xtime; - if ( atm_charge(vcc, skb->truesize) ) - { - struct sk_buff *new_skb; - - new_skb = alloc_skb_rx(); - if ( new_skb ) - { - if ( vcc->stats ) - atomic_inc(&vcc->stats->rx); - vcc->push(vcc, skb); - reg_desc.dataptr = (u32)new_skb->data >> 2; - - if ( len ) - *len = CELL_SIZE; - } - else - { - if ( vcc->stats ) - atomic_inc(&vcc->stats->rx_drop); - resize_skb_rx(skb, ppe_dev.aal5.rx_buffer_size, 0); - } - } - else - { - if ( vcc->stats ) - atomic_inc(&vcc->stats->rx_drop); - resize_skb_rx(skb, ppe_dev.aal5.rx_buffer_size, 0); - } - } - else - { -printk("reg_desc.err\n"); - - /* drop packet/cell */ - if ( vcc->qos.aal == ATM_AAL5 ) - { - UPDATE_VCC_STAT(conn, rx_err_pdu, 1); - - trailer = (struct rx_inband_trailer *)((u32)skb->data + ((reg_desc.byteoff + reg_desc.datalen + DMA_ALIGNMENT - 1) & ~ (DMA_ALIGNMENT - 1))); - if ( trailer->stw_crc ) - ppe_dev.connection[conn].aal5_vcc_crc_err++; - if ( trailer->stw_ovz ) - ppe_dev.connection[conn].aal5_vcc_oversize_sdu++; - } - if ( vcc->stats ) - atomic_inc(&vcc->stats->rx_err); - /* don't need resize */ - } - } - else - { -printk("ppe_dev.connection[%d].vcc == NULL\n", conn); - - ppe_dev.mib.wrx_drop_pdu++; - - /* don't need resize */ - } - } - - reg_desc.byteoff = 0; - reg_desc.datalen = ppe_dev.aal5.rx_buffer_size; - reg_desc.own = 1; - reg_desc.c = 0; - - /* write discriptor to memory */ - *desc = reg_desc; - -printk("leave mailbox_rx_irq_handler"); - - return 0; -} - -static inline void mailbox_tx_irq_handler(unsigned int conn) -{ - if ( ppe_dev.dma.tx_desc_alloc_flag[conn] ) - { - int desc_base; - int *release_pos; - struct sk_buff *skb; - - release_pos = &ppe_dev.dma.tx_desc_release_pos[conn]; - desc_base = ppe_dev.dma.tx_descriptor_number * (conn - QSB_QUEUE_NUMBER_BASE) + *release_pos; - while ( !ppe_dev.dma.tx_descriptor_base[desc_base].own ) - { - skb = ppe_dev.dma.tx_skb_pointers[desc_base]; - - ppe_dev.dma.tx_descriptor_base[desc_base].own = 1; // pretend PP32 hold owner bit, so that won't be released more than once, so allocation process don't check this bit - - if ( ++*release_pos == ppe_dev.dma.tx_descriptor_number ) - *release_pos = 0; - - if ( *release_pos == ppe_dev.dma.tx_desc_alloc_pos[conn] ) - { - ppe_dev.dma.tx_desc_alloc_flag[conn] = 0; - - atm_free_tx_skb_vcc(skb); - break; - } - - if ( *release_pos == 0 ) - desc_base = ppe_dev.dma.tx_descriptor_number * (conn - QSB_QUEUE_NUMBER_BASE); - else - desc_base++; - - atm_free_tx_skb_vcc(skb); - } - } -} - -#if defined(ENABLE_RX_QOS) && ENABLE_RX_QOS -static inline int check_desc_valid(unsigned int channel) -{ - int skb_base; - struct rx_descriptor *desc; - - skb_base = ppe_dev.dma.rx_descriptor_number * channel + ppe_dev.dma.rx_desc_read_pos[channel]; - desc = &ppe_dev.dma.rx_descriptor_base[skb_base]; - return !desc->own && desc->c ? 1 : 0; -} -#endif - -irqreturn_t mailbox_irq_handler(int irq, void *dev_id) -{ - int channel_mask; /* DMA channel accordant IRQ bit mask */ - int channel; - unsigned int rx_irq_number[MAX_RX_DMA_CHANNEL_NUMBER] = {0}; - unsigned int total_rx_irq_number = 0; - -printk("mailbox_irq_handler"); - - if ( !*MBOX_IGU1_ISR ) - return IRQ_RETVAL(1); - - channel_mask = 1; - channel = 0; - while ( channel < ppe_dev.dma.rx_total_channel_used ) - { - if ( (*MBOX_IGU1_ISR & channel_mask) ) - { - /* RX */ - /* clear IRQ */ - *MBOX_IGU1_ISRC = channel_mask; -printk(" RX: *MBOX_IGU1_ISR = 0x%08X\n", *MBOX_IGU1_ISR); - /* wait for mailbox cleared */ - while ( (*MBOX_IGU3_ISR & channel_mask) ); - - /* shadow the number of valid descriptor */ - rx_irq_number[channel] = WRX_DMA_CHANNEL_CONFIG(channel)->vlddes; - - total_rx_irq_number += rx_irq_number[channel]; - -printk("total_rx_irq_number = %d", total_rx_irq_number); -printk("vlddes = %d, rx_irq_number[%d] = %d, total_rx_irq_number = %d\n", WRX_DMA_CHANNEL_CONFIG(channel)->vlddes, channel, rx_irq_number[channel], total_rx_irq_number); - } - - channel_mask <<= 1; - channel++; - } - - channel_mask = 1 << (16 + QSB_QUEUE_NUMBER_BASE); - channel = QSB_QUEUE_NUMBER_BASE; - while ( channel - QSB_QUEUE_NUMBER_BASE < ppe_dev.dma.tx_total_channel_used ) - { - if ( (*MBOX_IGU1_ISR & channel_mask) ) - { -// if ( channel != 1 ) -// { -printk("TX irq error\n"); -// while ( 1 ) -// { -// } -// } - /* TX */ - /* clear IRQ */ - *MBOX_IGU1_ISRC = channel_mask; -printk(" TX: *MBOX_IGU1_ISR = 0x%08X\n", *MBOX_IGU1_ISR); - mailbox_tx_irq_handler(channel); - } - - channel_mask <<= 1; - channel++; - } - - #if defined(ENABLE_RX_QOS) && ENABLE_RX_QOS - channel = 0; - while ( total_rx_irq_number ) - { - switch ( channel ) - { - case RX_DMA_CH_CBR: - case RX_DMA_CH_OAM: - /* handle it as soon as possible */ - while ( rx_irq_number[channel] != 0 && mailbox_rx_irq_handler(channel, NULL) == 0 ) - { - rx_irq_number[channel]--; - total_rx_irq_number--; -printk("RX_DMA_CH_CBR, total_rx_irq_number = %d", total_rx_irq_number); -printk("RX_DMA_CH_CBR, total_rx_irq_number = %d, rx_irq_number[%d] = %d\n", total_rx_irq_number, channel, rx_irq_number[channel]); - /* signal firmware that descriptor is updated */ - mailbox_signal(channel, 0); - } -// if ( rx_irq_number[channel] != 0 ) -printk("RX_DMA_CH_CBR, rx_irq_number[channel] = %d", rx_irq_number[channel]); - break; - case RX_DMA_CH_VBR_RT: - /* WFQ */ - if ( rx_irq_number[RX_DMA_CH_VBR_RT] != 0 - && (rx_irq_number[RX_DMA_CH_VBR_NRT] == 0 || !check_desc_valid(RX_DMA_CH_VBR_NRT) || ppe_dev.dma.rx_weight[RX_DMA_CH_VBR_NRT] < ppe_dev.dma.rx_weight[RX_DMA_CH_VBR_RT]) - && (rx_irq_number[RX_DMA_CH_AVR] == 0 || !check_desc_valid(RX_DMA_CH_AVR) || ppe_dev.dma.rx_weight[RX_DMA_CH_AVR] < ppe_dev.dma.rx_weight[RX_DMA_CH_VBR_RT]) - ) - { - unsigned int len; - - if ( mailbox_rx_irq_handler(RX_DMA_CH_VBR_RT, &len) == 0 ) - { - rx_irq_number[RX_DMA_CH_VBR_RT]--; - total_rx_irq_number--; -printk("RX_DMA_CH_VBR_RT, total_rx_irq_number = %d", total_rx_irq_number); -printk("RX_DMA_CH_VBR_RT, total_rx_irq_number = %d, rx_irq_number[%d] = %d\n", total_rx_irq_number, channel, rx_irq_number[channel]); - /* signal firmware that descriptor is updated */ - mailbox_signal(channel, 0); - - len = (len + CELL_SIZE - 1) / CELL_SIZE; - if ( ppe_dev.dma.rx_weight[RX_DMA_CH_VBR_RT] <= len ) - ppe_dev.dma.rx_weight[RX_DMA_CH_VBR_RT] = ppe_dev.dma.rx_default_weight[RX_DMA_CH_VBR_RT] + ppe_dev.dma.rx_weight[RX_DMA_CH_VBR_RT] - len; - } - } -// if ( rx_irq_number[channel] != 0 ) -// { -printk("RX_DMA_CH_VBR_RT, rx_irq_number[channel] = %d, total_rx_irq_number = %d", rx_irq_number[channel], total_rx_irq_number); -// rx_irq_number[channel] = 0; -// total_rx_irq_number = 0; -// } - break; - case RX_DMA_CH_VBR_NRT: - /* WFQ */ - if ( rx_irq_number[RX_DMA_CH_VBR_NRT] != 0 - && (rx_irq_number[RX_DMA_CH_VBR_RT] == 0 || !check_desc_valid(RX_DMA_CH_VBR_RT) || ppe_dev.dma.rx_weight[RX_DMA_CH_VBR_RT] < ppe_dev.dma.rx_weight[RX_DMA_CH_VBR_NRT]) - && (rx_irq_number[RX_DMA_CH_AVR] == 0 || !check_desc_valid(RX_DMA_CH_AVR) || ppe_dev.dma.rx_weight[RX_DMA_CH_AVR] < ppe_dev.dma.rx_weight[RX_DMA_CH_VBR_NRT]) - ) - { - unsigned int len; - - if ( mailbox_rx_irq_handler(RX_DMA_CH_VBR_NRT, &len) == 0 ) - { - rx_irq_number[RX_DMA_CH_VBR_NRT]--; - total_rx_irq_number--; -printk("RX_DMA_CH_VBR_NRT, total_rx_irq_number = %d", total_rx_irq_number); -printk("RX_DMA_CH_VBR_NRT, total_rx_irq_number = %d, rx_irq_number[%d] = %d\n", total_rx_irq_number, channel, rx_irq_number[channel]); - /* signal firmware that descriptor is updated */ - mailbox_signal(channel, 0); - - len = (len + CELL_SIZE - 1) / CELL_SIZE; - if ( ppe_dev.dma.rx_weight[RX_DMA_CH_VBR_NRT] <= len ) - ppe_dev.dma.rx_weight[RX_DMA_CH_VBR_NRT] = ppe_dev.dma.rx_default_weight[RX_DMA_CH_VBR_NRT] + ppe_dev.dma.rx_weight[RX_DMA_CH_VBR_NRT] - len; - } - } -// if ( rx_irq_number[channel] != 0 ) -printk("RX_DMA_CH_VBR_NRT, rx_irq_number[channel] = %d", rx_irq_number[channel]); - break; - case RX_DMA_CH_AVR: - /* WFQ */ - if ( rx_irq_number[RX_DMA_CH_AVR] != 0 - && (rx_irq_number[RX_DMA_CH_VBR_RT] == 0 || !check_desc_valid(RX_DMA_CH_VBR_RT) || ppe_dev.dma.rx_weight[RX_DMA_CH_VBR_RT] < ppe_dev.dma.rx_weight[RX_DMA_CH_AVR]) - && (rx_irq_number[RX_DMA_CH_VBR_NRT] == 0 || !check_desc_valid(RX_DMA_CH_VBR_NRT) || ppe_dev.dma.rx_weight[RX_DMA_CH_VBR_NRT] < ppe_dev.dma.rx_weight[RX_DMA_CH_AVR]) - ) - { - unsigned int len; - - if ( mailbox_rx_irq_handler(RX_DMA_CH_AVR, &len) == 0 ) - { - rx_irq_number[RX_DMA_CH_AVR]--; - total_rx_irq_number--; -printk("RX_DMA_CH_AVR, total_rx_irq_number = %d", total_rx_irq_number); -printk("RX_DMA_CH_AVR, total_rx_irq_number = %d, rx_irq_number[%d] = %d\n", total_rx_irq_number, channel, rx_irq_number[channel]); - /* signal firmware that descriptor is updated */ - mailbox_signal(channel, 0); - - len = (len + CELL_SIZE - 1) / CELL_SIZE; - if ( ppe_dev.dma.rx_weight[RX_DMA_CH_AVR] <= len ) - ppe_dev.dma.rx_weight[RX_DMA_CH_AVR] = ppe_dev.dma.rx_default_weight[RX_DMA_CH_AVR] + ppe_dev.dma.rx_weight[RX_DMA_CH_AVR] - len; - } - } -// if ( rx_irq_number[channel] != 0 ) -printk("RX_DMA_CH_AVR, rx_irq_number[channel] = %d", rx_irq_number[channel]); - break; - case RX_DMA_CH_UBR: - default: - /* Handle it when all others are handled or others are not available to handle. */ - if ( rx_irq_number[channel] != 0 - && (rx_irq_number[RX_DMA_CH_VBR_RT] == 0 || !check_desc_valid(RX_DMA_CH_VBR_RT)) - && (rx_irq_number[RX_DMA_CH_VBR_NRT] == 0 || !check_desc_valid(RX_DMA_CH_VBR_NRT)) - && (rx_irq_number[RX_DMA_CH_AVR] == 0 || !check_desc_valid(RX_DMA_CH_AVR)) ) - if ( mailbox_rx_irq_handler(channel, NULL) == 0 ) - { - rx_irq_number[channel]--; - total_rx_irq_number--; -printk("RX_DMA_CH_UBR, total_rx_irq_number = %d, rx_irq_number[%d] = %d", total_rx_irq_number, channel, rx_irq_number[channel]); -printk("RX_DMA_CH_UBR, total_rx_irq_number = %d, rx_irq_number[%d] = %d\n", total_rx_irq_number, channel, rx_irq_number[channel]); - /* signal firmware that descriptor is updated */ - mailbox_signal(channel, 0); - } -printk("RX_DMA_CH_UBR, rx_irq_number[channel] = %d", rx_irq_number[channel]); - } - - if ( ++channel == ppe_dev.dma.rx_total_channel_used ) - channel = 0; - } - #else - channel = 0; - while ( total_rx_irq_number ) - { - while ( rx_irq_number[channel] != 0 && mailbox_rx_irq_handler(channel, NULL) == 0 ) - { - rx_irq_number[channel]--; - total_rx_irq_number--; - /* signal firmware that descriptor is updated */ - mailbox_signal(channel, 0); - } - - if ( ++channel == ppe_dev.dma.rx_total_channel_used ) - channel = 0; - } - #endif // defined(ENABLE_RX_QOS) && ENABLE_RX_QOS - return IRQ_RETVAL(1); -} - - |