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

📄 swpkt.c

📁 VIA VT6524 8口网管交换机源码
💻 C
字号:
/*
 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
 * All rights reserved.
 *
 * This software is copyrighted by and is the sole property of
 * VIA Networking Technologies, Inc. This software may only be used
 * in accordance with the corresponding license agreement. Any unauthorized
 * use, duplication, transmission, distribution, or disclosure of this
 * software is expressly forbidden.
 *
 * This software is provided by VIA Networking Technologies, Inc. "as is"
 * and any express or implied warranties, including, but not limited to, the
 * implied warranties of merchantability and fitness for a particular purpose
 * are disclaimed. In no event shall VIA Networking Technologies, Inc.
 * be liable for any direct, indirect, incidental, special, exemplary, or
 * consequential damages.
 *
 *
 * File:    swpkt.c
 *
 * Purpose:
 *
 * Author:  Tevin Chen
 *
 * Date:    Jan 08, 2002
 *
 * Functions:
 *
 * Revision History:
 *
 */


#if !defined(__TBIT_H__)
#include "tbit.h"
#endif
#if !defined(__SWITCH_H__)
#include "switch.h"
#endif
#if !defined(__SWREG_H__)
#include "swreg.h"
#endif
#if !defined(__SWPKT_H__)
#include "swpkt.h"
#endif




/*---------------------  Static Definitions  ------------------------*/
#define PTN_CPUIO_RDPKT_RDY         0x01
#define PTN_CPUIO_STATUS_OK         0x01

#define PTN_CPUIO_WRPKT_START       0x01
#define PTN_CPUIO_WRPKT_MIDDLE      0x02
#define PTN_CPUIO_WRPKT_END_TWO     0x04
#define PTN_CPUIO_WRPKT_END_ONE     0x05

#define PTN_CPUIO_INPUT_ENABLE      0x02    // Map to reg "Output" from switch
#define PTN_CPUIO_OUTPUT_ENABLE     0x01    // Map to reg "Input"  from switch


/*---------------------  Static Types  ------------------------------*/

/*---------------------  Static Macros  -----------------------------*/
// Used in SWPKT_vSendPkt()
#define PKTvReadB(pbyData)          do { *(pbyData) = x_byCpuPktData; } while (0)
#define PKTvWriteB(byData)          do { x_byCpuPktData = byData; } while (0)
#define SENDPKTBYTE()               do { PKTvWriteB(abyPktBuf[wPktPtr]); wPktPtr++; } while (0)

/*---------------------  Static Classes  ----------------------------*/

/*---------------------  Static Variables  --------------------------*/
static BYTE s_byRXSrcPort;

/*---------------------  Static Functions  --------------------------*/
static UINT16 s_wRecvPktOp (PBYTE abyPktBuf);
static void s_vSendPktOp (PBYTE abyPktBuf, UINT16 wPktLen);

/*---------------------  Export Variables  --------------------------*/
UINT8   SWPKTg_abyEpktBuf[EPKT_BUF_SIZE];   /* The packet buffer that contains
                                            incoming packets. */
UINT8*  SWPKTg_pbyEpktAppData;              /* The pointer points to
                                            application data. */
UINT16  SWPKTg_wEpktBufLen;




void SWPKT_vDrvInit (void)
{
    // Forwarding ARP to CPU and enable CPU IO
    SWREG_vWriteB(FWD_FWD_ARP_TO_CPU, TRUE);
    SWREG_vWriteB(CPUIO_CFG, PTN_CPUIO_INPUT_ENABLE | PTN_CPUIO_OUTPUT_ENABLE);
}


UINT16 SWPKT_wRecvPkt (void)
{
    return s_wRecvPktOp(SWPKTg_abyEpktBuf);
}


static UINT16 s_wRecvPktOp (PBYTE abyPktBuf)
{
    UINT16  wPktLen, uu;



    // If no packet to receive, return
    if (SWREG_bIfBitsOff(CPUIO_RD_PKT_RDY, PTN_CPUIO_RDPKT_RDY))
        return 0;

    // Get CPU forward port mask = source port
    SWREG_vReadB(CPUIO_RD_PKT_ATTRIB, &s_byRXSrcPort);

    // Get packet content routine
    // Get packet size (if larger than MAX_ETH_PKT_SIZE, truncate it)
    SWREG_vReadW(CPUIO_RD_PKT_BYTE_CNT, &wPktLen);
    wPktLen = (wPktLen <= MAX_ETH_PKT_SIZE) ? wPktLen : MAX_ETH_PKT_SIZE;

    // CPU IF is 8-bit width => read 1 byte once
    // If odd length => read 1 dummy byte; else, no dummy byte
    for (uu = 0; uu < wPktLen + (wPktLen & 0x01); uu++) {
        PKTvReadB(abyPktBuf + uu);
    }

    // Set TX vlan tag = RX vlan tag
    SWREG_vReadW(CPUIO_RD_PKT_VLAN_TAG, &uu);
    SWREG_vWriteW(CPUIO_WR_PKT_VLAN_TAG, uu);

    // check RD_PKT_STATUS
    if (SWREG_bIfBitsOn(CPUIO_RD_PKT_STATUS, PTN_CPUIO_STATUS_OK))
        return wPktLen;
    else
        return 0;   // if not OK, it maybe bad packet.
}


void SWPKT_vSendPkt(void)
{
    UINT16 ii;


    if (SWPKTg_wEpktBufLen > 40 + EPKT_LLH_LEN) {
        for (ii = 0; ii < SWPKTg_wEpktBufLen - 40 - EPKT_LLH_LEN; ii++)
            SWPKTg_abyEpktBuf[ii+40+EPKT_LLH_LEN] = SWPKTg_pbyEpktAppData[ii];
    }

    s_vSendPktOp(SWPKTg_abyEpktBuf, SWPKTg_wEpktBufLen);
}


static void s_vSendPktOp (PBYTE abyPktBuf, UINT16 wPktLen)
{
    UINT16  wPktPtr = 0, uu;
    BOOL    bTxTagged;
    


    // TX tag/untag = RX tag/untag
    bTxTagged = BITbIsBitOn(s_byRXSrcPort, 0x80);
    s_byRXSrcPort &= 0x1F;
    if (bTxTagged)
        SWREG_vWriteDW(FWD_CPU_VLAN_TAG_RULE, (UINT32)0x01 << s_byRXSrcPort);
    else
        SWREG_vWriteDW(FWD_CPU_VLAN_TAG_RULE, (UINT32)0);
    // TX port = RX port
    SWREG_vWriteDW(FWD_CPU_PM, (UINT32)0x01 << s_byRXSrcPort);
    
    // check destination port is linkup
    for (uu = 0; uu < 0xFFFF; uu++)
        if (SWREG_vIsSpecBitOn(PHY_LINK_STATUS, s_byRXSrcPort))
            break;
    if (uu == 0xFFFF) {
        return;
    }

    //
    // Begin to transmit packet (i.e. write to packet data register)
    // CPU IF is 8-bit width => write 1 byte once
    //

    // Notify start of frame and transmit 2 bytes of data
    SWREG_vWriteB(CPU_WR_PKT_CMD, PTN_CPUIO_WRPKT_START);
    SENDPKTBYTE();
    SENDPKTBYTE();

    // Notify middle of frame and transmit until 1 or 2 bytes left
    SWREG_vWriteB(CPU_WR_PKT_CMD, PTN_CPUIO_WRPKT_MIDDLE);
    for (uu = wPktPtr; uu < wPktLen - 2 + (wPktLen & 0x01); uu++) {
        SENDPKTBYTE();
    }

    // Notify end of frame and transmit the last 2 bytes
    // (if odd packet => the last one is dummy byte)
    if ((wPktLen & 0x01) != 0)
        SWREG_vWriteB(CPU_WR_PKT_CMD, PTN_CPUIO_WRPKT_END_ONE);
    else
        SWREG_vWriteB(CPU_WR_PKT_CMD, PTN_CPUIO_WRPKT_END_TWO);
    SENDPKTBYTE();
    SENDPKTBYTE();
}

⌨️ 快捷键说明

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