transmit3.c

来自「在接入服务器测试在收发链路层数据包」· C语言 代码 · 共 244 行

C
244
字号
//------------------------------------------------------------------------------------
//                                                                      
//                   I N T E L   P R O P R I E T A R Y                   
//                                                                      
//     COPYRIGHT (c) 2001 BY  INTEL  CORPORATION.  ALL RIGHTS          
//     RESERVED.   NO  PART  OF THIS PROGRAM  OR  PUBLICATION  MAY      
//     BE  REPRODUCED,   TRANSMITTED,   TRANSCRIBED,   STORED  IN  A    
//     RETRIEVAL SYSTEM, OR TRANSLATED INTO ANY LANGUAGE OR COMPUTER    
//     LANGUAGE IN ANY FORM OR BY ANY MEANS, ELECTRONIC, MECHANICAL,    
//     MAGNETIC,  OPTICAL,  CHEMICAL, MANUAL, OR OTHERWISE,  WITHOUT    
//     THE PRIOR WRITTEN PERMISSION OF :                                
//                                                                       
//                         INTEL  CORPORATION                            
//                                                                      
//                      2200 MISSION COLLEGE BLVD                        
//                                                                       
//                SANTA  CLARA,  CALIFORNIA  95052-8119                  
//                                                                       
//------------------------------------------------------------------------------------


//////////////////////////////////////////////////////
// Include libraries
//////////////////////////////////////////////////////
#include "ixp.h"
#include "rtl.c"
#include "mem_map3.h"


//////////////////////////////////////////////////////
// Constants
//////////////////////////////////////////////////////
#define UINT unsigned int


//////////////////////////////////////////////////////
// Type Defs
//////////////////////////////////////////////////////
typedef struct
{
	UINT base_addr;
} tfifo_addr;

// struct for xfer register use in sram and tfifo_write.
typedef struct
{
	UINT data[2];
} tfifo_ctl_wd;



/**************************************************************/
// Determines if port and TFIFO element are ready for transmit
//
// inputs:	port	- which port to xmit on
//			inptr	- which tfifo element to use for xmit
//
UINT okToTransmit(UINT port, UINT inptr)
{

	__declspec(sram_read_reg) UINT tx_rdy;	//local copy of the Transmit Ready Flags
	__declspec(sram_read_reg) UINT tx_outptr;	//local copy of the Transmit Pointer
	UINT rdyOk;		//if not zero, xmit ready flags are ok
	UINT ptrOk;		//if not zero, xmit state machine is ready
					//to xmit tfifo element number "inptr"

	//////////////////////////////////////////////////////
	// Read the Transmit Ready Flags and Transmit
	// Pointer from the Transmit State Machine
	//////////////////////////////////////////////////////
	csr_read(&tx_rdy, xmit_rdy_lo, 1, no_signal);
	csr_read(&tx_outptr, xmit_ptr, 1, ctx_swap);

	rdyOk = tx_rdy & (1<<port);
	ptrOk = (!(tx_outptr - inptr));

	if(rdyOk && ptrOk) return(1);
	else return(0);

}

/**************************************************************/
void main()
{

	__declspec(dram) long long *p_packet;		//address of packet
	__declspec(sram) UINT *p_descriptor;		//address of descriptor
//	__declspec(tbuf) long long *p_status_word;	//address of tfifo control word
	__declspec(sram) UINT *p_led;				//address of led


	volatile __declspec(t_fifo) void *p_status_word;
	__declspec(sram_write_reg) tfifo_ctl_wd status_word;
	tfifo_ctl_wd current_desc;

	UINT current_port;		//port to transmit on
	UINT current_inptr;		//keeps track of TFIFO element for xmit

//	UINT current_desc[2]; //local copy of packet descriptor
//	UINT status_word[2];	//used to format TFIFO control field

	//variables used to format indirect references
	csr_fast_write_ind_t fw_ind;
	fifo_read_write_ind_t dram_tfifo_write_ind;

	//////////////////////////////////////////////////////
	//  Check Context Number
	//
	//  Run only one transmit thread.  
	//  If we are not running as context 0,then permanently swap out 
	//////////////////////////////////////////////////////
	if(ctx() == 0)
	{

		p_led = (__declspec(sram) UINT *)0x00742000;
//		*p_led = 7;
		//get actual address from mem_map
		p_packet = (__declspec(dram) long long *)DATA_ADDR;
		p_descriptor = (__declspec(sram) UINT *)DESCRIPTOR_ADDR;

		//do some setup on indirect refs
		fw_ind.ov_data = 1;
		dram_tfifo_write_ind.ov_ref_count = 1;

		//initialize inptr to point to first element of TFIFO
		current_inptr = 0;
		
		//////////////////////////////////////////////////////
		// Start of Transmit Loop   
		// Wait for a signal from the Recieve thread that a 
		// packet is in the buffer and ready to be transmitted
		//////////////////////////////////////////////////////
		while(1)
		{
			ctx_wait(inter_thread);
			*p_led = 8;

			//////////////////////////////////////////////////////
			// We have been signalled by the receive thread.
			// Read the packet descriptor from SRAM
			//////////////////////////////////////////////////////
			current_desc.data[0] = (UINT)(*p_descriptor);


			//; DESCRIPTOR FORMAT
			//; +-----+-------+---------+---+---+----+----+
			//; | res | num qw|num bytes|EOP|SOP|skip|port|
			//; | 31  | 15:13 |  12:10  | 9 | 8 | 7  |6:0 |
			//; +-----+-------+---------+---+---+----+----+

			current_desc.data[0] &= ~0x7;	//heli add for change port to 2
			current_desc.data[0] |= 0x2;	//heli add for change port to 2
			current_port = (current_desc.data[0]) & 0x1f;

			while(!okToTransmit(current_port, current_inptr))
			{
				//////////////////////////////////////////////////////
				// Before transmitting the packet data check the availability
				// of both the MAC port and next Transmit FIFO Element.  Both
				// must be ready before we move the packet data to the FIFO
				//
				// Use the port number to test the Transmit Ready Flags and
				// out TFIFO Element pointer to test the Transmit State
				// Machine pointer.  If either is not ready, re-read the
				// appropiate CSRs
				//////////////////////////////////////////////////////
			}
			*p_led = 9;


			//////////////////////////////////////////////////////
			// At this point both the port and FIFO element are ready.
			// Move the packet directly from SDRAM to the FIFO Element.
			// 
			// First, set the indirect reference fields appropiately,
			// then use the intrinsic dram function to perform the move.
			// 
			//////////////////////////////////////////////////////

			//Figure the address of the TFIFO element to write to.
			//Each element has 8 quadwords, so multiplying our element
			//number by 8 will yield the correct qw address.
			dram_tfifo_write_ind.qword_addr = current_inptr<<3;

			//take the number of qw's to transfer from the descriptor
			dram_tfifo_write_ind.ref_count = ((current_desc.data[0])>>13) & 0x7;

			sdram_t_fifo_write_ind(p_packet, 4, dram_tfifo_write_ind, queue_default, ctx_swap);


			//////////////////////////////////////////////////////
			// Write the Control word to the T-FIFO element 
			//////////////////////////////////////////////////////

			//Calculate the address of the T-FIFO control word.  The address 
			//is the input pointer multiplied by 2 (length of control and
			//prepend fields) plus 128 (offset into T-FIFO to start of
			// control/prepend fields).
			p_status_word = (void*)(2 * current_inptr + 128);

			//The descriptor definition matches that of the control 
			//word so it is written to the control word as-is!
			status_word = current_desc;
			t_fifo_write(&status_word, p_status_word, 1, ctx_swap);


			//////////////////////////////////////////////////////
			// Validate the TFIFO entry.
			// First place the TFIFO element number into the indirect
			// reference variable, then issue a fast_write to validate
			// the TFIFO element. This tells the IX Bus Interface Unit
			// to transmit the packet data to the MAC
			//////////////////////////////////////////////////////
			fw_ind.data = current_inptr;
			csr_fast_write_ind(xmit_validate, 0x0, fw_ind);

			//Issue an inter_thread_signal to the receive thread to
			//let it know it can get another packet.
			csr_fast_write(inter_thd_sig, 0x0);

			//////////////////////////////////////////////////////
			// Increment our FIFO pointer for next time around
			// Roll the pointer over if it has reached 16
			//////////////////////////////////////////////////////
			current_inptr++;
			if(current_inptr > 15) current_inptr = 0;
			*p_led = 11;

		} //while

	//////////////////////////////////////////////////////
	// FINISHED PROCESSING ALL PACKETS                   /
	//////////////////////////////////////////////////////

	} //if context 0

	else  //not context 0
	{
		ctx_wait(kill);
	}

} //transmit3 main

⌨️ 快捷键说明

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