/*
<:copyright-BRCM:2016:DUAL/GPL:standard

   Broadcom Proprietary and Confidential.(c) 2016 Broadcom
   All Rights Reserved

Unless you and Broadcom execute a separate written software license
agreement governing use of this software, this software is licensed
to you under the terms of the GNU General Public License version 2
(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
with the following added to such license:

   As a special exception, the copyright holders of this software give
   you permission to link this software with independent modules, and
   to copy and distribute the resulting executable under terms of your
   choice, provided that you also meet, for each linked independent
   module, the terms and conditions of the license of that module.
   An independent module is a module which is not derived from this
   software.  The special exception does not apply to any modifications
   of the software.

Not withstanding the above, under no circumstances may you combine
this software in any way with any other Broadcom software provided
under a license other than the GPL, without Broadcom's express prior
written consent.

:>
 */

#include "bcmos_system.h"
#include "bcmtr_pcie.h"
#include "bcmolt_tr_pcie_specific.h"

extern f_bcmtr_int bcmtr_pcie_rx_irq_handler;
extern f_bcmtr_int bcmtr_pcie_tx_irq_handler;
static bcmos_fastlock isr_lock;

/***************************************************************/
/* need to pass thru all the devices - check if irq is SHARED */
/***************************************************************/
static int bcmtr_rx_isr(int irq, void *isr_info)
{
    uint32_t isr_reg;
    uint32_t mask_reg;
    long flags;
    int handled = 0;
    bcm_pcied_isr_data *isr_data = (bcm_pcied_isr_data *)isr_info;

    flags = bcmos_fastlock_lock(&isr_lock);

    isr_reg = bcm_pci_read32((uint32_t*)(isr_data->pcie_reg_base + DMA_INTR_STATUS));
    mask_reg = ~bcm_pci_read32((uint32_t*)(isr_data->pcie_reg_base + DMA_INTR_MASK_STATUS));

    if ((isr_reg & mask_reg)& DMA_TX_DONE_MASK)
    {
        /* handle TX DONE interrupt */
        isr_data->tx_done_num++;

        if (bcmtr_pcie_tx_irq_handler)
            bcmtr_pcie_tx_irq_handler(isr_data->device);

        handled = 1;
    }

    if ((isr_reg & mask_reg ) & DMA_RX_DONE_MASK)
    {
        /* handle RX DONE interrupt */
        isr_data->rx_done_num++;

        if (bcmtr_pcie_rx_irq_handler)
            bcmtr_pcie_rx_irq_handler(isr_data->device);

        handled = 1;
    }

    if (isr_reg & (DMA_RX_ERROR_MASK | DMA_TX_ERROR_MASK))
    {
        if (isr_reg & DMA_RX_ERROR_MASK)
            isr_data->rx_err_num++;
        if (isr_reg & DMA_TX_ERROR_MASK)
            isr_data->tx_err_num++;
        /* clear interrupt error interrupt */
        bcm_pci_write32((uint32_t*)(isr_data->pcie_reg_base + DMA_INTR_CLEAR), DMA_RX_ERROR_MASK | DMA_TX_ERROR_MASK);
        handled = 1;
    }

    bcmos_fastlock_unlock(&isr_lock, flags);

    return handled;
}

void bcmtr_connect_isr(void *isr_info)
{
    uint32_t    flags = 0;

    bcm_pcied_isr_data *isr_data = (bcm_pcied_isr_data *)isr_info;
    bcmos_fastlock_init(&isr_lock, flags);
    /* connect interrupt to system cpu - 0 */
    bcmos_int_connect((int)isr_data->rx_irq, 0, BCMOS_IRQ_SHARED, bcmtr_rx_isr, "dmaisr", isr_data);
}

#ifdef __KERNEL__
EXPORT_SYMBOL(bcmtr_connect_isr);
#endif


