⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swpkt.c

📁 vt6528芯片交换机API函数和文档运行程序
💻 C
📖 第 1 页 / 共 3 页
字号:
        // Copy packet from page
        //
        u16PktLen = sg_NetDev.apRBufRx[sg_NetDev.u32RxBufEnque]->pkb_u16BufLen;
        pu8PktBuf = sg_NetDev.apRBufRx[sg_NetDev.u32RxBufEnque]->pkb_au8Buffer;

        // Check if return to page0
        if ((g_u32RdPktCurr + u16PktLen) > g_u32RdStopPageAddr ) {
            u16BlkSize = g_u32RdStopPageAddr - g_u32RdPktCurr;
            STR_pvMemcpy(pu8PktBuf, (void *)g_u32RdPktCurr, u16BlkSize);
            STR_pvMemcpy(pu8PktBuf + u16BlkSize, (void *)g_u32RdStrtPageAddr, u16PktLen - u16BlkSize);
        }
        else
            STR_pvMemcpy(pu8PktBuf, (void *)g_u32RdPktCurr, u16PktLen);

        // Next free page start address
        SWPCICSR_vReadU32(RD_PKT_CURR_ADDR, &g_u32RdPktCurr );

        // at this moment, data is really valid on the buffer, so increase rx queue counter here
        ADD_ONE_WITH_WRAP_AROUND(sg_NetDev.u32RxBufEnque, RBUF_RX_BUF_NUM);
        sg_NetDev.u32RxBufQueueNum++;
    }

    sg_bMuxRdPktInDma = FALSE;
}


void ISR_vWrPktDmaCompleted (void)
{
    if (SWREG_bIsBitsOnU8(CPUIF_WR_PKT_DMA_STATUS, DMA_STATUS_FAIL)) {
        g_NetStat.u32PktTxBad++;
        // it maybe send failed, but we don't do re-send now
        DBG_PRN_PKT_TX(" PKTTX: error, DMA fail.");
    }
    else {
        DBG_PRN_PKT_TX(" PKTTX: DMA ok.");
        if (SWREG_bIsBitsOnU8(CPUPORT_INPUT_PORT_STATUS, WR_PKT_STATUS_TRANS_OK)) {
            g_NetStat.u32PktTxGood++;
            DBG_PRN_PKT_TX(" PKTTX: tx ok.");
        }
        else {
            g_NetStat.u32PktTxBad++;
            // it maybe send failed, but we don't do re-send now
            DBG_PRN_PKT_TX(" PKTTX: error, tx fail.");
        }
    }

    // no matter tx is ok or failed, decrease tx queue
    ADD_ONE_WITH_WRAP_AROUND(sg_NetDev.u32TxBufDeque, RBUF_TX_BUF_NUM);
    sg_NetDev.u32TxBufQueueNum--;

    sg_bMuxWrPktInDma = FALSE;
}

#else   // !__SWITCH_CPUIF_PCI

//
// Interrupt Service Routines: Read Packet DMA Completed
//
void ISR_vRdPktDmaCompleted (void)
{
    if (SWREG_bIsBitsOnU8(CPUIF_RD_PKT_DMA_STATUS, DMA_STATUS_FAIL)) {
        // if not OK, it maybe bad packet.
        g_NetStat.u32PktRxBad++;
        DBG_PRN_PKT(" PKT: error, rx bad packet.");
    }
    else {
        // at this moment, data is really valid on the buffer, so increase rx queue counter here
        ADD_ONE_WITH_WRAP_AROUND(sg_NetDev.u32RxBufEnque, RBUF_RX_BUF_NUM);
        sg_NetDev.u32RxBufQueueNum++;
        g_NetStat.u32PktRxGood++;
        DBG_PRN_PKT(" PKT: rx good packet.");
    }

    sg_bMuxRdPktInDma = FALSE;
}


//
// Interrupt Service Routines: Write Packet DMA Completed
//
void ISR_vWrPktDmaCompleted (void)
{
    if (SWREG_bIsBitsOnU8(CPUIF_WR_PKT_DMA_STATUS, DMA_STATUS_FAIL)) {
        g_NetStat.u32PktTxBad++;
        // it maybe send failed, but we don't do re-send now
        DBG_PRN_PKT_TX(" PKTTX: error, DMA fail.");
    }
    else {
        DBG_PRN_PKT_TX(" PKTTX: DMA ok.");
        if (SWREG_bIsBitsOnU8(CPUPORT_INPUT_PORT_STATUS, WR_PKT_STATUS_TRANS_OK)) {
            g_NetStat.u32PktTxGood++;
            DBG_PRN_PKT_TX(" PKTTX: tx ok.");
        }
        else {
            g_NetStat.u32PktTxBad++;
            // it maybe send failed, but we don't do re-send now
            DBG_PRN_PKT_TX(" PKTTX: error, tx fail.");
        }
    }

    // no matter tx is ok or failed, decrease tx queue
    ADD_ONE_WITH_WRAP_AROUND(sg_NetDev.u32TxBufDeque, RBUF_TX_BUF_NUM);
    sg_NetDev.u32TxBufQueueNum--;

    sg_bMuxWrPktInDma = FALSE;
}

#endif  // !__SWITCH_CPUIF_PCI

#else   // __PKT_PIO

void ISR_vRdPktDmaCompleted (void)
{
}

void ISR_vWrPktDmaCompleted (void)
{
}
#endif  // __PKT_PIO




void SWPKT_vDrvOpen (void)
{
    UINT    uu;
    UINT8   u8Cfg = 0;

    sg_NetDev.u32RxBufEnque = 0;
    sg_NetDev.u32RxBufDeque = 0;
    sg_NetDev.u32RxBufQueueNum = 0;

    sg_NetDev.u32TxBufEnque = 0;
    sg_NetDev.u32TxBufDeque = 0;
    sg_NetDev.u32TxBufQueueNum = 0;

    sg_pfnHookRecv = NULL;

    for (uu = 0; uu < RBUF_RX_BUF_NUM; uu++)
        sg_NetDev.apRBufRx[uu] = &sg_aRBufRx[uu];
    for (uu = 0; uu < RBUF_TX_BUF_NUM; uu++)
        sg_NetDev.apRBufTx[uu] = &sg_aRBufTx[uu];

#ifdef __SWITCH_CPUIF_PCI
    // PCI packet buffer configuration
    SWPCI_vMstrInit();
#endif

#if !__PKT_PIO
    sg_bMuxRdPktInDma = FALSE;
    sg_bMuxWrPktInDma = FALSE;
#endif

    STR_pvMemset((PUINT8)&g_NetStat, 0, sizeof(SNetStat));


    // Forwarding ARP to CPU
    // Patch : none IP SNAP with tag packet will always be ARP packet
    // Disable forward ARP to CPU port
#if 0
    SWREG_vWriteU8(FWDCTL_ARP_CFG, ARP_CFG_REQ_TO_CPU);
#endif
    // enable CPU IO
    SWREG_vBitsOnU8(CPUPORT_CFG, CPU_CFG_RX_ENABLE | CPU_CFG_TX_ENABLE);

    // set CPU bus width, interface, and bus endian
#if !__SWITCH_CPUIF_PKT8

    SWREG_vReadU8(CPUIF_HOSTIF_CFG, &u8Cfg);
    #ifdef  __BIG_ENDIAN
        #if !__PKT_PIO
            #ifdef __CPU_S3C2510A
                u8Cfg |= (HOSTIF_BUS_WIDTH16 | HOSTIF_TRANS_DMA);   //why not use HOSTIF_BUS_ENDIAN_BIG TBD?
            #else
                u8Cfg |= (HOSTIF_BUS_ENDIAN_BIG | HOSTIF_BUS_WIDTH16 | HOSTIF_TRANS_DMA);
            #endif
        #else   //pio
            u8Cfg = (u8Cfg & ~(HOSTIF_TRANS_DMA)) | HOSTIF_BUS_WIDTH16;
        #endif
    #else   //Little endian
        u8Cfg |= HOSTIF_BUS_WIDTH16;
        #if !__PKT_PIO
            u8Cfg |= HOSTIF_TRANS_DMA;
        #else   //pio
            u8Cfg &= ~(HOSTIF_TRANS_DMA);
        #endif
    #endif
    SWREG_vWriteU8(CPUIF_HOSTIF_CFG, u8Cfg);

#else   //8bit, pio
    u8Cfg = 0;
    SWREG_vBitsOffU8(CPUIF_HOSTIF_CFG, HOSTIF_BUS_WIDTH16 | HOSTIF_TRANS_DMA | HOSTIF_BUS_ENDIAN_BIG);
#endif


#if !__PKT_PIO
    //enable DMA channel
    SWREG_vWriteU8(CPUIF_REQ_CFG, REQ_EN);

    //set the DMA data transfer count
    SWREG_vWriteU16(CPUIF_DMA_ABT_WP_WRR_CNT, DEF_WP_DMA_WRR_CNT);
    SWREG_vWriteU16(CPUIF_DMA_ABT_RP_WRR_CNT, DEF_RP_DMA_WRR_CNT);

    //set DMA arbitration policy
    SWREG_vWriteU8(CPUIF_DMA_ABT_POLICY, DMA_ABT_POLICY_RR);

    PLAT_vDma0Enable();
    PLAT_vDma1Enable();
#endif

#ifdef __SWITCH_CPUIF_PCI
    // clear all interrupt
    SWPCICSR_vWriteU32(ISR0_OFF, ISR_STATUS_ALL);
    // enable HCI interrupt mask, ISR0/ISR1/ISR2 interrupts
    SWPCICSR_vWriteU32(IMR_OFF, ( (((UINT32)ISR3_ALL) << 24) | ( ((UINT32)ISR2_ALL) << 16) |
                              (((UINT32)ISR1_ALL) << 8) | ((UINT32)ISR0_ALL) )
                              );
#endif

    // clear all interrupt
    SWREG_vWriteU16(CPUIF_IRQ_STATUS, IRQ_STATUS_ALL);
    // enable switch interrupt mask, Tx/Rx/LinkChange/TxComp/RxComp interrupts
    SWREG_vWriteU8(CPUIF_IRQ_MASK, IRQ_STATUS_LINK_CHG | IRQ_STATUS_PKT_RX | IRQ_STATUS_PKT_TX |
                                   IRQ_STATUS_WRPKT_DMA_DONE | IRQ_STATUS_RDPKT_DMA_DONE);
}


void SWPKT_vDrvClose (void)
{
    // disable switch interrupt mask
    SWREG_vWriteU8(CPUIF_IRQ_MASK, 0);

    // disable CPU IO
    SWREG_vBitsOffU8(CPUPORT_CFG, CPU_CFG_RX_ENABLE | CPU_CFG_TX_ENABLE);
    // stop forwarding ARP to CPU
    SWREG_vWriteU8(FWDCTL_ARP_CFG, 0);
}


void SWPKT_vSetHookFnRx (PFN_HOOK_PV pfnHook)
{
    PLAT_vCpuCriticalEnter();
    sg_pfnHookRecv = pfnHook;
    PLAT_vCpuCriticalExit();
}


void SWPKT_vGetMacAddress (UINT8* pu8MacAddr)
{
    UINT    uu;

    for (uu = 0; uu < MAC_ADDR_SIZE; uu++)
        if (uu >= 2)
            SWREG_vReadU8(FWDCTL_SWITCH_MAC_ADDR0 + (5 - uu), pu8MacAddr + uu);
        else
            SWREG_vReadU8(FWDCTL_SWITCH_MAC_ADDR1 + (1 - uu), pu8MacAddr + uu);
}


void SWPKT_vSetMacAddress (UINT8* pu8MacAddr)
{
    UINT    uu;

    for (uu = 0; uu < MAC_ADDR_SIZE; uu++)
        if (uu >= 2)
            SWREG_vWriteU8(FWDCTL_SWITCH_MAC_ADDR0 + (5 - uu), pu8MacAddr[uu]);
        else
            SWREG_vWriteU8(FWDCTL_SWITCH_MAC_ADDR1 + (1 - uu), pu8MacAddr[uu]);
}


/*
 * Description : SWPKT_bRecvPkt only used by Rx Packet Tag Remove Disable(Reg0x0100 bit[2] is 0).
 *               Packet include 4 bytes vlan tag if tagged packet.
 */
BOOL SWPKT_bRecvPkt (SRBuf* pPktBuf)
{
    PUINT8   pu8NonCacheBuf;



    // protect the whole section prevent variables ruined by other threads
    PLAT_vCpuCriticalEnter();

    // if rx buffer is empty, get packet failed
    if (sg_NetDev.u32RxBufQueueNum == 0) {
        PLAT_vCpuCriticalExit();
        return FALSE;
    }
    DBG_PRN_PKT(" PKT: received packet.");

    // copy structure
#if !__PKT_PIO
    // Because the cache has the old data, we read from non-cache address
    pu8NonCacheBuf = (PUINT8)(((UINT32)sg_NetDev.apRBufRx[sg_NetDev.u32RxBufDeque]->pkb_au8Buffer) | PLAT_ASIC_NON_CACHE_ADDR);
#else
    pu8NonCacheBuf = sg_NetDev.apRBufRx[sg_NetDev.u32RxBufDeque]->pkb_au8Buffer;
#endif

    //Packet Tag Remove Disable. Remove tag information from packet content
    if (sg_NetDev.apRBufRx[sg_NetDev.u32RxBufDeque]->pkb_bTagged){
        pPktBuf->pkb_u16BufLen = sg_NetDev.apRBufRx[sg_NetDev.u32RxBufDeque]->pkb_u16BufLen - 4;   //-4 means 4 bytes tag
        STR_pvMemcpy(pPktBuf->pkb_au8Buffer, pu8NonCacheBuf , 12);
        STR_pvMemcpy(pPktBuf->pkb_au8Buffer + 12, pu8NonCacheBuf + 16, pPktBuf->pkb_u16BufLen - 12);    // +16 means 6 bytes DMAC, 6 bytes SMAC, and 4 bytes Tag
    }
    else{
        pPktBuf->pkb_u16BufLen = sg_NetDev.apRBufRx[sg_NetDev.u32RxBufDeque]->pkb_u16BufLen;
        STR_pvMemcpy(pPktBuf->pkb_au8Buffer, pu8NonCacheBuf, pPktBuf->pkb_u16BufLen);
    }
    pPktBuf->pu8AppData = NULL;
    pPktBuf->u16AppDataOffset = 0;
    pPktBuf->pkb_u8SrcPortId = sg_NetDev.apRBufRx[sg_NetDev.u32RxBufDeque]->pkb_u8SrcPortId;
    pPktBuf->pkb_bTagged = sg_NetDev.apRBufRx[sg_NetDev.u32RxBufDeque]->pkb_bTagged;
    pPktBuf->pkb_u16VID = sg_NetDev.apRBufRx[sg_NetDev.u32RxBufDeque]->pkb_u16VID;
    pPktBuf->pkb_u8Priority = sg_NetDev.apRBufRx[sg_NetDev.u32RxBufDeque]->pkb_u8Priority;

    ADD_ONE_WITH_WRAP_AROUND(sg_NetDev.u32RxBufDeque, RBUF_RX_BUF_NUM);
    sg_NetDev.u32RxBufQueueNum--;
    PLAT_vCpuCriticalExit();

    return TRUE;
}


BOOL SWPKT_bSendPkt (SRBuf* pPktBuf)
{
    BOOL    bTxTagged;
    UINT8   u8TxPort;
    UINT16  u16TxIndex;
    PUINT8  pu8TxPktBuf;
    UINT16  u16TxPktLen;


    u16TxPktLen = pPktBuf->pkb_u16BufLen;
    // check if valid packet length
    if ((u16TxPktLen == 0) || (ETH_PKT_MAX_LEN < u16TxPktLen)) {
        g_NetStat.u32ErrorTxSize++;
        DBG_PRN_PKT_TX(" PKTTX: packet size error.");
        return FALSE;
    }

    // protect the whole section prevent variables ruined by other threads
    PLAT_vCpuCriticalEnter();

    // tx queue is full, not to send
    if (sg_NetDev.u32TxBufQueueNum >= RBUF_TX_BUF_NUM) {
        PLAT_vCpuCriticalExit();
        g_NetStat.u32ErrorTxBufDrop++;
        DBG_PRN_PKT_TX(" PKTTX: Drop packet due to no tx buffer.");
        return FALSE;
    }

    // check TX is tag/untag by bit-7
    bTxTagged = pPktBuf->pkb_bTagged;
    u8TxPort = pPktBuf->pkb_u8SrcPortId;

    pu8TxPktBuf = sg_NetDev.apRBufTx[sg_NetDev.u32TxBufEnque]->pkb_au8Buffer;

    if (pPktBuf->pu8AppData == NULL) {
        STR_pvMemcpy(pu8TxPktBuf, pPktBuf->pkb_au8Buffer, u16TxPktLen);
    }
    else {
        u16TxIndex = pPktBuf->u16AppDataOffset;
        STR_pvMemcpy(pu8TxPktBuf, pPktBuf->pkb_au8Buffer, u16TxIndex);
        // Copy APP_DATA
        STR_pvMemcpy(pu8TxPktBuf + u16TxIndex, pPktBuf->pu8AppData, u16TxPktLen - u16TxIndex);
    }

    // VT3268 need TX packet >=64 ( i.e. 60 w/o FCS)
    if (u16TxPktLen < ETH_PKT_MIN_LEN ) {
        STR_pvMemset(pu8TxPktBuf + u16TxPktLen, 0x0, ETH_PKT_MIN_LEN - u16TxPktLen);
        u16TxPktLen = pPktBuf->pkb_u16BufLen = ETH_PKT_MIN_LEN;
    }

    // copy structure
    sg_NetDev.apRBufTx[sg_NetDev.u32TxBufEnque]->pkb_u16BufLen = u16TxPktLen;
    sg_NetDev.apRBufTx[sg_NetDev.u32TxBufEnque]->pu8AppData = pPktBuf->pu8AppData; //TOCHECK
    sg_NetDev.apRBufTx[sg_NetDev.u32TxBufEnque]->u16AppDataOffset = pPktBuf->u16AppDataOffset; //TOCHECK
    sg_NetDev.apRBufTx[sg_NetDev.u32TxBufEnque]->pkb_u8SrcPortId = pPktBuf->pkb_u8SrcPortId;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -