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

📄 eth_stub.c

📁 opentcp_mcf5282原代码
💻 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 + -