📄 eth_stub.c
字号:
/*********************************************************************************
File: eth_stub.c
Date: 22.1.2004
Version: 0.1
Author: Jari Lahti (jari.lahti@violasystems.com)
Description: Wrapper functions betw. Motorola fec, nif & nbuf code and OpenTCP
internals
Version Info: 22.1.2004 - First version (JaL)
26.3.2004 - Check for Ethernet rx frame length (JaL)
*********************************************************************************/
#include "src/common/m5282evb.h"
#include "src/ethernet/nif.h"
#include "src/ethernet/fec.h"
#include "datatypes.h"
#include "debug.h"
#include "eth_stub.h"
/* structure we use to keep track on tx & rx stuff */
/* this is needed for easy integration of opentcp principles */
/* and Motorola eth drivers without lot of re-code */
struct
{
INT16 unprocessed; /* Number of unprocessed rx packets */
INT16 next_receive; /* The entry in RxNBUF we receive */
NBUF* cur_rxframe; /* current nbuf entry we are using */
NBUF* cur_txframe; /* current nbuf entry we are using */
UINT8* rxp; /* Read pointer */
UINT8* txp; /* Write pointer */
} eth_wrapper;
/* Frame we receive */
struct otcp_ethframe otcp_rxframe;
/* Frame we send */
struct otcp_ethframe otcp_txframe;
/********************************************************************************
Function: eth_stub_init
Parameters: void
Return val: void
Date: 22.1.2004
Desc: Call this function on init before entering to main loop.
Just initializes the eth_wrapper
*********************************************************************************/
void eth_stub_init (void)
{
eth_wrapper.unprocessed = 0;
eth_wrapper.next_receive = 0;
eth_wrapper.cur_rxframe = NULL;
eth_wrapper.cur_txframe = NULL;
eth_wrapper.rxp = NULL;
eth_wrapper.txp = NULL;
}
/********************************************************************************
Function: opentcp_fechandler
Parameters: NIF *nif - network interface
Return val: void
Date: 22.1.2004
Desc: This function is called by nif_protocol_handler in order to
supply received Ethernet packet. We just increase the number of
unprocessed packets OpenTCP to poll.
*********************************************************************************/
void opentcp_fechandler (NIF *nif)
{
if( (eth_wrapper.unprocessed + 1) > eth_wrapper.unprocessed )
eth_wrapper.unprocessed++;
}
/********************************************************************************
Function: eth_stub_isframe
Parameters: NIF *nif - network interface
Return val: INT16 : (<0) - Error
(0) - No pending frames
(>0) - There are pending frames
Date: 22.1.2004
Desc: Checks do we have any pending frame
*********************************************************************************/
INT16 eth_stub_isframe (NIF *nif)
{
NBUF* fr;
eth_frame_hdr *ethframe;
int i;
if(eth_wrapper.unprocessed == 0)
return(0);
for(i=0; i< NUM_RXBDS; i++)
{
fr = nbuf_give_frame(eth_wrapper.next_receive);
if(fr != NULL)
break;
if(eth_wrapper.next_receive++ >= NUM_RXBDS)
eth_wrapper.next_receive = 0;
}
if(fr == NULL)
return(0);
eth_wrapper.cur_rxframe = fr;
/* Store packet info for OpenTCP internals */
/* Point to the ethernet header of this packet */
ethframe = (eth_frame_hdr *)&fr->data[ETH_HDR_OFFSET];
/* Check for errors */
if(fr->status & RX_BD_TR)
{
/* Truncated */
DEBUGOUT("Received truncated packet\n");
eth_stub_dumpframe(nif);
return(-1);
}
if (fr->status & RX_BD_L)
{
if(fr->status & RX_BD_OV)
{
/* Receive FIFO overrun */
DEBUGOUT("Receive FIFO overrun\n");
eth_stub_dumpframe(nif);
return(-1);
}
if(fr->status & RX_BD_NO)
{
/* Non-octet aligned frame */
DEBUGOUT("Received non-octet aligned frame\n");
eth_stub_dumpframe(nif);
return(-1);
}
if(fr->status & RX_BD_LG)
{
/* Frame length violation */
//DEBUGOUT("Frame length violation\n");
//eth_stub_dumpframe(nif);
//return(-1);
}
if(fr->status & RX_BD_CR)
{
/* CRC Fail */
DEBUGOUT("Received CRC failed\n");
eth_stub_dumpframe(nif);
return(-1);
}
}
/* Too big? */
if(fr->length > ETH_MAX_SIZE)
{
DEBUGOUT("Too big Ethernet Frame\r\n");
eth_stub_dumpframe(nif);
return(-1);
}
for(i=0; i<ETH_ADDRESS_LEN; i++)
otcp_rxframe.destination[i] = ethframe->dest[i];
for(i=0; i<ETH_ADDRESS_LEN; i++)
otcp_rxframe.source[i] = ethframe->src[i];
otcp_rxframe.framesize = fr->length;
otcp_rxframe.protocol = ethframe->type;
otcp_rxframe.bufindex = ETH_HDR_SIZE;
eth_wrapper.rxp = fr->data;
return(1);
}
/********************************************************************************
Function: eth_stub_dumpframe
Parameters: NIF *nif - network interface
Return val: INT16 : (<0) - Error
(=>0) - OK, frame released
Date: 22.1.2004
Desc: Releases the frame and decreases the number of pending packets
*********************************************************************************/
INT16 eth_stub_dumpframe (NIF *nif)
{
int old_ipl;
NBUF* fr;
if(eth_wrapper.cur_rxframe == NULL)
{
return(0);
}
/* This routine alters shared data. Disable interrupts! */
old_ipl = asm_set_ipl(6);
fr = eth_wrapper.cur_rxframe;
eth_wrapper.cur_rxframe = NULL;
if(eth_wrapper.unprocessed)
eth_wrapper.unprocessed--;
eth_wrapper.next_receive++;
if(eth_wrapper.next_receive >= NUM_RXBDS)
eth_wrapper.next_receive = 0;
eth_wrapper.rxp = NULL;
/* Release buffer */
nif->rx_free(fr);
/* Restore previous IPL */
asm_set_ipl(old_ipl);
return(1);
}
/********************************************************************************
Function: eth_stub_seekread
Parameters: NIF *nif - network interface
UINT16 pos - position from the start of read buffer
Return val: INT16 : (<0) - Error
(=>0) - OK
Date: 22.1.2004
Desc: Moves the read pointer to the given position from start
*********************************************************************************/
INT16 eth_stub_seekread (NIF *nif, UINT16 pos)
{
if(eth_wrapper.rxp == NULL)
return(-1);
eth_wrapper.rxp = eth_wrapper.cur_rxframe->data;
eth_wrapper.rxp += pos;
return(0);
}
/********************************************************************************
Function: eth_stub_read
Parameters: NIF *nif - network interface
Return val: UINT8 - read data
Date: 22.1.2004
Desc: Return one byte of data from rx buffer and advances read pointer.
TODO:More efficient to make this a MACRO
*********************************************************************************/
UINT8 eth_stub_read (NIF *nif)
{
//TODO:overflow check
return(*eth_wrapper.rxp++);
}
/********************************************************************************
Function: eth_stub_read_buf
Parameters: NIF *nif - network interface
UINT8* buf - buffer for data
UINT16 buflen - number of bytes requested
Return val: INT16: (-1) - Error
(>=0) - Number of bytes read
Date: 22.1.2004
Desc: Reads multiple bytes from rx buffer and advances read pointer
*********************************************************************************/
INT16 eth_stub_read_buf (NIF *nif, UINT8* buf, UINT16 buflen)
{
//TODO:overflow check
memcpy(buf, eth_wrapper.rxp, buflen);
eth_wrapper.rxp += buflen;
return(buflen);
}
/********************************************************************************
Function: eth_stub_txalloc
Parameters: NIF *nif - network interface
Return val: INT16: (-1) - Error
(>=0) - OK, tx buffer allocated
Date: 22.1.2004
Desc: Allocates tx buffer from nbuf
*********************************************************************************/
INT16 eth_stub_txalloc (NIF *nif)
{
/* Are we already assembling a frame? */
if(eth_wrapper.cur_txframe != NULL)
{
/* yep, release it */
nif->tx_free(eth_wrapper.cur_txframe);
eth_wrapper.cur_txframe = NULL;
}
/* try to get the buffer */
//TODO: try few times
eth_wrapper.cur_txframe = nif->tx_alloc();
/* how it went? */
if(eth_wrapper.cur_txframe == NULL)
{
DEBUGOUT("Error allocating Ethernet TX Buffer\r\n");
return(-1);
}
eth_wrapper.txp = eth_wrapper.cur_txframe->data + ETH_HDR_SIZE;
/* it's now allocated, next assemble data and send */
return(1);
}
/********************************************************************************
Function: eth_stub_writeheader
Parameters: NIF *nif - network interface
struct otcp_ethframe* frame - ethernet header info
Return val: INT16: (-1) - Error
(>=0) - OK
Date: 22.1.2004
Desc: Writes ethernet header to tx buffer
*********************************************************************************/
INT16 eth_stub_writeheader (NIF *nif, struct otcp_ethframe* frame)
{
/* Are we having a buffer? */
if(eth_wrapper.cur_txframe == NULL)
return(-1);
/* Write destination ethernet address */
eth_wrapper.cur_txframe->data[ETH_HDR_OFFSET + 0] = frame->destination[0];
eth_wrapper.cur_txframe->data[ETH_HDR_OFFSET + 1] = frame->destination[1];
eth_wrapper.cur_txframe->data[ETH_HDR_OFFSET + 2] = frame->destination[2];
eth_wrapper.cur_txframe->data[ETH_HDR_OFFSET + 3] = frame->destination[3];
eth_wrapper.cur_txframe->data[ETH_HDR_OFFSET + 4] = frame->destination[4];
eth_wrapper.cur_txframe->data[ETH_HDR_OFFSET + 5] = frame->destination[5];
/* Write source ethernet address. */
eth_wrapper.cur_txframe->data[ETH_HDR_OFFSET + 6] = frame->source[0];
eth_wrapper.cur_txframe->data[ETH_HDR_OFFSET + 7] = frame->source[1];
eth_wrapper.cur_txframe->data[ETH_HDR_OFFSET + 8] = frame->source[2];
eth_wrapper.cur_txframe->data[ETH_HDR_OFFSET + 9] = frame->source[3];
eth_wrapper.cur_txframe->data[ETH_HDR_OFFSET + 10] = frame->source[4];
eth_wrapper.cur_txframe->data[ETH_HDR_OFFSET + 11] = frame->source[5];
/* Write frame type */
eth_wrapper.cur_txframe->data[ETH_HDR_OFFSET + 12] = (uint8)((frame->protocol & 0xFF00) >> 8);
eth_wrapper.cur_txframe->data[ETH_HDR_OFFSET + 13] = (uint8)(frame->protocol & 0x00FF);
return(1);
}
/********************************************************************************
Function: eth_stub_send
Parameters: NIF *nif - network interface
UINT16 len - length of packet without the eth header & CRR
Return val: INT16: (-1) - Error
(>=0) - OK (number of bytes written)
Date: 22.1.2004
Desc: Sends the ethernet frame
*********************************************************************************/
INT16 eth_stub_send (NIF *nif, UINT16 len)
{
int i;
if(eth_wrapper.cur_txframe == NULL)
return(-1);
//TODO: Insert pad bytes?
eth_wrapper.cur_txframe->length = len + ETH_HDR_SIZE;
i = nif->send(nif, eth_wrapper.cur_txframe);
/* The nif->send releases buffer */
eth_wrapper.cur_txframe = NULL;
if(!i)
return(-1);
return(len);
}
/********************************************************************************
Function: eth_stub_write
Parameters: NIF *nif - network interface
UINT8 dat - data byte to write
Return val: INT16: (-1) - Error
(>=0) - OK (number of bytes written)
Date: 22.1.2004
Desc: Writes single byte to tx buffer and increases write pointer
*********************************************************************************/
INT16 eth_stub_write (NIF *nif, UINT8 dat)
{
if(eth_wrapper.cur_txframe == NULL)
return(-1);
//TODO: Check overflow
*eth_wrapper.txp++ = dat;
return(1);
}
/********************************************************************************
Function: eth_stub_write_buf
Parameters: NIF *nif - network interface
UINT8* buf - data to write
UINT16 buflen - number of bytes to write
Return val: INT16: (-1) - Error
(>=0) - OK (number of bytes written)
Date: 22.1.2004
Desc: Writes multiple bytes to tx buffer and increases write pointer
*********************************************************************************/
INT16 eth_stub_write_buf (NIF *nif, UINT8* buf, UINT16 buflen)
{
if(eth_wrapper.cur_txframe == NULL)
return(-1);
//TODO: Check overflow
memcpy(eth_wrapper.txp, buf, buflen);
eth_wrapper.txp += buflen;
return(buflen);
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -