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

📄 swpkt.c

📁 vt6528芯片交换机API函数和文档运行程序
💻 C
📖 第 1 页 / 共 3 页
字号:
    sg_NetDev.apRBufTx[sg_NetDev.u32TxBufEnque]->pkb_bTagged = pPktBuf->pkb_bTagged;
    sg_NetDev.apRBufTx[sg_NetDev.u32TxBufEnque]->pkb_u16VID = pPktBuf->pkb_u16VID;
    sg_NetDev.apRBufTx[sg_NetDev.u32TxBufEnque]->pkb_u8Priority = pPktBuf->pkb_u8Priority;
    sg_NetDev.apRBufTx[sg_NetDev.u32TxBufEnque]->pkb_u32TxMbrPrtMsk = pPktBuf->pkb_u32TxMbrPrtMsk;
    sg_NetDev.apRBufTx[sg_NetDev.u32TxBufEnque]->pkb_u32TxTagPrtMsk = pPktBuf->pkb_u32TxTagPrtMsk;


    ADD_ONE_WITH_WRAP_AROUND(sg_NetDev.u32TxBufEnque, RBUF_TX_BUF_NUM);
    sg_NetDev.u32TxBufQueueNum++;
    PLAT_vCpuCriticalExit();

    // if this is the first packet in the tx queue, have to trigger it
    if ((sg_NetDev.u32TxBufQueueNum <= 1) || sg_bFirstTxFail) {
        sg_bFirstTxFail = FALSE;
        if (TMR_iSetTimer(1, (PFN_CALLBACK_TIMER)Timer_vSendPkt, NULL) == FAILED)
            Timer_vSendPkt();
    }

    return TRUE;
}


#if !__PKT_PIO

#ifdef __SWITCH_CPUIF_PCI

/*
 * Description : s_vDmaStartRecv only used by Rx Packet Tag Remove Disable(Reg0x0100 bit[2] is 0).
 *               Packet include 4 bytes CRC.
 *               Packet also include 4 bytes vlan tag if tagged packet.
 */
static void s_vDmaStartRecv (SRBuf* pRBuf)
{
    UINT8   u8HCICsr;


    // Get RX vlan tag
    SWREG_vReadU16(CPUPORT_RD_PKT_VLAN_TAG, &pRBuf->pkb_u16VID);
    pRBuf->pkb_u8Priority = (pRBuf->pkb_u16VID & 0xE000) >> 13;
    pRBuf->pkb_u16VID = pRBuf->pkb_u16VID & 0x0FFF;

   // Get source port id
    SWREG_vReadU8(CPUPORT_RD_PKT_ATTRIB, &pRBuf->pkb_u8SrcPortId);
    pRBuf->pkb_bTagged = (pRBuf->pkb_u8SrcPortId & RD_PKT_ATTRIB_TAGGED) != 0;
    pRBuf->pkb_u8SrcPortId = pRBuf->pkb_u8SrcPortId & RD_PKT_ATTRIB_PORTID_MSK;

    // Get packet size (if larger than ETH_PKT_MAX_LEN, truncate it)
    SWREG_vReadU16(CPUPORT_RD_PKT_BYTE_CNT, &pRBuf->pkb_u16BufLen);
    pRBuf->pkb_u16BufLen = (pRBuf->pkb_u16BufLen <= (ETH_PKT_MAX_LEN+4)) ? pRBuf->pkb_u16BufLen : (ETH_PKT_MAX_LEN+4);
    // +4 is 4 bytes CRC

    //
    // master read packet procedure:
    //

    //  After all initialize setting finished, trigger the master packet read
    //  by writing the HCI CSR 0x08h (PS2H_GO = 1).
    u8HCICsr = DCR0_PS2H_GO;
    PCIIO_Write8((g_u32SwIoBA + DCR0_OFF), u8HCICsr);

    //Remove 4 bytes CRC, because Tag Remove Disable
    pRBuf->pkb_u16BufLen -= 4;
}


static void s_vDmaStartSend (SRBuf* pRBuf)
{
    UINT8   u8HCICsr;
    UINT16  u16BlkSize;
    UINT32  u32Bnry;
    UINT16  u16VlanTag;



    // Set Tag rule
    SWREG_vWriteU32(CPUPORT_WR_PKT_EGRS_RULE, pRBuf->pkb_u32TxTagPrtMsk);
    // Set TX vlan tag
    u16VlanTag = pRBuf->pkb_u16VID | (pRBuf->pkb_u8Priority << 13);
    SWREG_vWriteU16(CPUPORT_WR_PKT_VLAN_TAG, u16VlanTag);

    // Set TX port mask
    SWREG_vWriteU32(CPUPORT_WR_PKT_PM, pRBuf->pkb_u32TxMbrPrtMsk);
    // Proc. of TX

    // Copy packet to page
    SWPCICSR_vReadU32(TD_PKT_BNRY_ADDR, &u32Bnry );
    // Check if return to page0
    if ((u32Bnry + pRBuf->pkb_u16BufLen) > g_u32TdStopPageAddr )
    {
        u16BlkSize = g_u32TdStopPageAddr - u32Bnry;
        STR_pvMemcpy((void *)u32Bnry, (void *)pRBuf->pkb_au8Buffer, u16BlkSize);
        STR_pvMemcpy((void *)g_u32TdStrtPageAddr, (void *)(pRBuf->pkb_au8Buffer + u16BlkSize), pRBuf->pkb_u16BufLen - u16BlkSize);
    }
    else
        STR_pvMemcpy((void *)u32Bnry, (void *)pRBuf->pkb_au8Buffer, pRBuf->pkb_u16BufLen);

    //  Program the HCI CSR 0x5Ch (TD_PKT_BC) the packet byte count.
    SWPCICSR_vWriteU16(TD_PKT_BC, pRBuf->pkb_u16BufLen);

    //  After all initialize setting finished, trigger the master packet read
    //      by writing the HCI CSR 0x08h (PH2S_GO = 1).
    u8HCICsr = DCR0_PH2S_GO;
    PCIIO_Write8((g_u32SwIoBA + DCR0_OFF), u8HCICsr);
}

#else   // not __SWITCH_CPUIF_PCI

/*
 * Description : s_vDmaStartRecv only used by Rx Packet Tag Remove Disable(Reg0x0100 bit[2] is 0).
 *               Packet include 4 bytes CRC.
 *               Packet also include 4 bytes vlan tag if tagged packet.
 */
static void s_vDmaStartRecv(SRBuf* pRBuf)
{
    UINT8  u8PadCnt;


    // Get RX vlan tag
    SWREG_vReadU16(CPUPORT_RD_PKT_VLAN_TAG, &pRBuf->pkb_u16VID);
    pRBuf->pkb_u8Priority = (pRBuf->pkb_u16VID & 0xE000) >> 13;
    pRBuf->pkb_u16VID = pRBuf->pkb_u16VID & 0x0FFF;

    // Get source port id
    SWREG_vReadU8(CPUPORT_RD_PKT_ATTRIB, &pRBuf->pkb_u8SrcPortId);
    pRBuf->pkb_bTagged = (pRBuf->pkb_u8SrcPortId & RD_PKT_ATTRIB_TAGGED) != 0;
    pRBuf->pkb_u8SrcPortId = pRBuf->pkb_u8SrcPortId & RD_PKT_ATTRIB_PORTID_MSK;

    // Get packet size (if larger than ETH_PKT_MAX_LEN, truncate it)
    SWREG_vReadU16(CPUPORT_RD_PKT_BYTE_CNT, &pRBuf->pkb_u16BufLen);
    pRBuf->pkb_u16BufLen = (pRBuf->pkb_u16BufLen <= (ETH_PKT_MAX_LEN+4)) ? pRBuf->pkb_u16BufLen : (ETH_PKT_MAX_LEN+4);
    // +4 means 4 bytes CRC

    // Proc. of RX
    SWREG_vWriteU8(CPUIF_RD_PKT_DMA_MODE, DMA_MODE_DEMAND | RP_DMA_CH);
    // Set transfer counter, and write packet length to Switch register
    u8PadCnt = (4 - (pRBuf->pkb_u16BufLen % 4)) % 4;
    SWREG_vWriteU16(CPUIF_RD_PKT_DMA_TRANS_CNT, pRBuf->pkb_u16BufLen + u8PadCnt);
    // Set channel ready to Switch register, and let CPU start DMA
    PLAT_vDma0GenIntr(FALSE);
    PLAT_vDma0TrigRx(pRBuf->pkb_au8Buffer, (pRBuf->pkb_u16BufLen + u8PadCnt) / 2, (UINT32)sg_pioCpuPktData16);
    SWREG_vWriteU8(CPUIF_RD_PKT_DMA_CH_RDY, DMA_CH_RDY);
    //Remove 4 bytes CRC, because Tag Remove Disable
    pRBuf->pkb_u16BufLen -= 4;
}


static void s_vDmaStartSend(SRBuf* pRBuf)
{
    UINT8   u8PadCnt;
    BOOL    bTxTagged;
    UINT8   u8TxPort;
    UINT16  u16VlanTag;


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

    // Set Tag rule
    SWREG_vWriteU32(CPUPORT_WR_PKT_EGRS_RULE, pRBuf->pkb_u32TxTagPrtMsk);

    // Set TX vlan tag
    u16VlanTag = pRBuf->pkb_u16VID | (pRBuf->pkb_u8Priority << 13);
    SWREG_vWriteU16(CPUPORT_WR_PKT_VLAN_TAG, u16VlanTag);

    // Set TX port mask
    SWREG_vWriteU32(CPUPORT_WR_PKT_PM, pRBuf->pkb_u32TxMbrPrtMsk);

    // Proc. of TX
    // Set DMA mode, padding count and channel select.
    SWREG_vWriteU8(CPUIF_WR_PKT_DMA_MODE, ((pRBuf->pkb_u16BufLen % 4)<<2) | DMA_MODE_DEMAND | WP_DMA_CH);
    // Set transfer counter, and write packet length to Switch register
    u8PadCnt = (4 - (pRBuf->pkb_u16BufLen % 4)) % 4;
    SWREG_vWriteU16(CPUIF_WR_PKT_DMA_TRANS_CNT, pRBuf->pkb_u16BufLen + u8PadCnt);
    // Set channel ready to Switch register, and let CPU start DMA
#if __PBUS_DMA_2_CHNNL
    PLAT_vDma1GenIntr(FALSE);
    PLAT_vDma1TrigTx(pRBuf->pkb_au8Buffer, (pRBuf->pkb_u16BufLen + u8PadCnt) / 2, (UINT32)sg_pioCpuPktData16);
#else
    PLAT_vDma0GenIntr(FALSE);
    PLAT_vDma0TrigTx(pRBuf->pkb_au8Buffer, (pRBuf->pkb_u16BufLen + u8PadCnt) / 2, (UINT32)sg_pioCpuPktData16);
#endif
    SWREG_vWriteU8(CPUIF_WR_PKT_DMA_CH_RDY, DMA_CH_RDY);
}

#endif

#else   //#if __PKT_PIO

/*
 * Description : s_wRecvPktOp only used by Rx Packet Tag Remove Disable(Reg0x0100 bit[2] is 0).
 *               Packet include 4 bytes CRC.
 *               Packet also include 4 bytes vlan tag if tagged packet.
 */
static UINT16 s_wRecvPktPIO (PUINT8 pu8RxBuf, PUINT8 pu8SrcPortId, PBOOL pbTagged, PUINT16 pu16VID, PUINT8 pu8Priority)
{
    UINT16  wRxIndex;
    UINT16  u16RxLen;
    UINT8   u8PadCnt;

    // Get RX vlan tag
    SWREG_vReadU16(CPUPORT_RD_PKT_VLAN_TAG, pu16VID);
    *pu8Priority = (*pu16VID & 0xE000) >> 13;
    *pu16VID = *pu16VID & 0x0FFF;

    // Get source port id
    SWREG_vReadU8(CPUPORT_RD_PKT_ATTRIB, pu8SrcPortId);
    *pbTagged = (*pu8SrcPortId & RD_PKT_ATTRIB_TAGGED) != 0;
    *pu8SrcPortId = *pu8SrcPortId & RD_PKT_ATTRIB_PORTID_MSK;

    // Get packet size (if larger than ETH_PKT_MAX_LEN, truncate it)
    SWREG_vReadU16(CPUPORT_RD_PKT_BYTE_CNT, &u16RxLen);
    u16RxLen = (u16RxLen <= (ETH_PKT_MAX_LEN+4)) ? u16RxLen : (ETH_PKT_MAX_LEN+4);
    // +4 is 4 bytes CRC

    //
    // Packet Rx Routine:
    //

    // Packet is transferred in 4-bytes block.
    // The packet transfer count should add some padding to be multiple of 4-bytes if the original packet size is not the multiple of block.
    u8PadCnt = (4 - (u16RxLen % 4)) % 4;

#ifdef __SWITCH_CPUIF_PCI

    // PCI transaction is DW-based(4 bytes), read 4 byte once
    for (wRxIndex = 0; wRxIndex < ((u16RxLen+u8PadCnt) / 4); wRxIndex++) {
        PCIIO_Read32( (g_u32SwIoBA + PDP_OFF), (PUINT32)(pu8RxBuf + (wRxIndex * 4)));
    }

#else   // not __SWITCH_CPUIF_PCI

    #if __SWITCH_CPUIF_PKT8
        // CPU IF is 8-bit width, read 1 byte once,
        for (wRxIndex = 0; wRxIndex < (u16RxLen+u8PadCnt); wRxIndex++) {
            PKTvReadB(pu8RxBuf + wRxIndex);
        }
    #else
        // CPU IF is 16-bit width, read 2 byte once
        for (wRxIndex = 0; wRxIndex < ((u16RxLen+u8PadCnt) / 2); wRxIndex++) {
            PKTvReadW(((PUINT16)pu8RxBuf) + wRxIndex);
        }
    #endif

#endif



    // check RD_PKT_STATUS
    if (SWREG_bIsBitsOnU8(CPUPORT_OUTPUT_PORT_STATUS, RD_PKT_TRANS_OK)) {
        g_NetStat.u32PktRxGood++;
        DBG_PRN_PKT(" PKT: good packet.");

        //Remove 4 bytes CRC, because Tag Remove Disable
        u16RxLen -= 4;
        return u16RxLen;
    }

    // if not OK, it maybe bad packet.
    g_NetStat.u32PktRxBad++;
    DBG_PRN_PKT(" PKT: error, bad packet.");

    return 0;
}

static void s_vSendPktPIO(SRBuf* pRBuf)
{
    BOOL    bTxTagged;
    UINT8   u8TxPort;
    UINT16  u16VlanTag;
    PUINT8  pu8TxBuf;
    UINT16  u16TxLen;
    UINT16  u16TxIndex;
    UINT8   u8PadCnt;
    UINT16  u16Block;

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

    // set Tag rule
    SWREG_vWriteU32(CPUPORT_WR_PKT_EGRS_RULE, pRBuf->pkb_u32TxTagPrtMsk);
    // Set TX vlan tag
    u16VlanTag = pRBuf->pkb_u16VID | (pRBuf->pkb_u8Priority << 13);
    SWREG_vWriteU16(CPUPORT_WR_PKT_VLAN_TAG, u16VlanTag);

    // Set TX port mask
    SWREG_vWriteU32(CPUPORT_WR_PKT_PM, pRBuf->pkb_u32TxMbrPrtMsk);

    //
    // Packet Tx Routine:
    //
    pu8TxBuf = pRBuf->pkb_au8Buffer;
    u16TxLen = pRBuf->pkb_u16BufLen;
    u16TxIndex = 0;

    u8PadCnt = (4 - (u16TxLen % 4)) % 4;
    u16Block = (u16TxLen + u8PadCnt) / 4;

    // Program Write Packet Command to 1 to transmit the first block of packet data.
    SWREG_vWriteU8(CPUIF_CPU_PKT_CMD, CPU_PKT_CMD_WR_PKT_START);
#ifdef __SWITCH_CPUIF_PCI

    PCIIO_Write32( (g_u32SwIoBA + PDP_OFF), *((PUINT32)pu8TxBuf) );
    pu8TxBuf += 4;
    u16TxIndex += 4;

#else   // not __SWITCH_CPUIF_PCI
    PKTvWriteBlock();
#endif

    // Program Write Packet Command to 2 to transmit the rest of the packet except the last block.
    SWREG_vWriteU8(CPUIF_CPU_PKT_CMD, CPU_PKT_CMD_WR_PKT_MIDDLE);
    for (; u16TxIndex < (u16Block - 1)*4 ; ) {  //-1 means last block
        if ((pRBuf->pu8AppData != NULL) && (u16TxIndex == pRBuf->u16AppDataOffset))
            pu8TxBuf = pRBuf->pu8AppData;

#ifdef __SWITCH_CPUIF_PCI

    PCIIO_Write32( (g_u32SwIoBA + PDP_OFF), *((PUINT32)pu8TxBuf) );
    pu8TxBuf += 4;
    u16TxIndex += 4;

#else   // not __SWITCH_CPUIF_PCI

    #if __SWITCH_CPUIF_PKT8
            PKTvWriteB();
    #else
            PKTvWriteW();
    #endif

#endif

    }

    // Program Write Packet Command to one of the end of frame command to transmit the last block of the packet.
    // If the byte count of the actual packet data in the last block is 1, program the command to 4.
    // Similarly, if the byte count of the actual packet data in the last block is 2, 3, or 4,
    // program the command to 5, 6, or 7 respectively.

    SWREG_vWriteU8(CPUIF_CPU_PKT_CMD, CPU_PKT_CMD_WR_PKT_4_VALID - u8PadCnt);

    for (; u16TxIndex < (u16Block*4) ; ) {
        if ((pRBuf->pu8AppData != NULL) && (u16TxIndex == pRBuf->u16AppDataOffset))
            pu8TxBuf = pRBuf->pu8AppData;
#ifdef __SWITCH_CPUIF_PCI

    PCIIO_Write32( (g_u32SwIoBA + PDP_OFF), *((PUINT32)pu8TxBuf) );
    pu8TxBuf += 4;
    u16TxIndex += 4;

#else   // not __SWITCH_CPUIF_PCI

    #if __SWITCH_CPUIF_PKT8
            PKTvWriteB();
    #else
            PKTvWriteW();
    #endif

#endif

    }

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

#endif


⌨️ 快捷键说明

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