📄 swpkt.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 + -