receive3.c

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

C
236
字号
//------------------------------------------------------------------------------------
//                                                                      
//                   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"


#define UINT unsigned int

//////////////////////////////////////////////////////
// Constants
//////////////////////////////////////////////////////

#define MAX_PACKETS		5		//number of packets to receive

#define MYCONTEXT		0		//absolute context number (0-23)
#define CURRENT_PORT	1		//MAC port number to check for packets


//; RCV_REQ FORMAT
//; +--------+-----+----+-----+-----+-----+----+-----+------+-------+-----+------+
//; | fetch 9| msg |stat| elem| elem|seq# |1or2|misc | sig  | thread| mac | port |
//; |        | pkt |    | #2  | #1  |     |    |     | sched|       |     |      |
//; |     29 |28:27| 26 |25:22|21:18|17:16| 15 |14:12|  11  | 10:6  | 5:3 | 2:0  |
//; +--------+-----+----+-----+-----+-----+----+-----+------+-------+-----+------+
#define THIS_RR		((CURRENT_PORT<<18)|(MYCONTEXT<<6)|(CURRENT_PORT))



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

	__declspec(dram) long long *packet;		//address for packet storage in DRAM
	__declspec(sram) UINT *p_descriptor;	//address for descriptor in SRAM
	__declspec(sram) UINT *p_led;			//address of led

	UINT rcv_rdy;			//contains ready flags
	UINT rcv_cmd;			//holds RCV_CNTL register info after a packet receive
	UINT rfifo_entry;		//extract rfifo element # from RCV_CNTL
	UINT packet_count;		//tracks the number of packets received so far

	UINT current_rr;		//hold formatted receive request
	UINT port_mask;			//bitmask to check RCV_RDY_LO register

	__declspec(sram_read_reg) UINT temp_csr;			//temp register used to read CSR's
	UINT temp_desc;			//temporary storage while formatting descriptor

	fifo_read_write_ind_t dram_rfifo_read_ind; //used for formatting indirect ref

	//////////////////////////////////////////////////////
	//  Check Context Number
	//
	//  Run only one receive thread on context 0; if we are
	//  not running as context 0,then permanently swap out.
	//
	//////////////////////////////////////////////////////

	if(ctx() == 0)
	{
		p_led = (__declspec(sram) UINT *)0x00742000;
		*p_led = 0;

		//get addresses from mem_map
		packet = (__declspec(dram) long long *)DATA_ADDR;
		p_descriptor = (__declspec(sram) UINT *)DESCRIPTOR_ADDR;

		current_rr = THIS_RR;
		port_mask =	1<<CURRENT_PORT;

		//for this project, all packets are 64bytes
		dram_rfifo_read_ind.ov_ref_count = 1;
		dram_rfifo_read_ind.ref_count = 0x08;

		packet_count = 0;

		//////////////////////////////////////////////////////
		// Start of Loop
		//
		// If we have received the number of packets contained
		// in the GPR max_packets, then stop processing.
		//
		//////////////////////////////////////////////////////
//		while(packet_count < MAX_PACKETS)
		while(1) //receive packets forever!
		{

			//////////////////////////////////////////////////////
			// Read Receive Ready Flags until our port has data
			//
			// In RCV_RDY_LO, bit 1 corresponds to port 1,
			// so we can see if our port is ready by checking
			// if bit 1 is set (by ANDING WITH PORTMASK)
			//////////////////////////////////////////////////////
			rcv_rdy = 0;

			while(!(rcv_rdy & port_mask))
			{
				//just keep reading RCV_RDY_LO
				//until our port has data
				csr_read(&temp_csr, rcv_rdy_lo, 1, ctx_swap);
				rcv_rdy = temp_csr;
				//note the use of a temporary register above:
				// this is done b/c when using the intrinsics
				// to access CSR's, transfer registers are used
				// and hence the parameter to the csr_read,
				// "temp_csr" will have all the restrictions
				// of a normal transfer register..
			}
			*p_led = 1;

			//////////////////////////////////////////////////////
			// Write the Receive Request
			//////////////////////////////////////////////////////
		    csr_write(current_rr, rcv_req, no_signal);


			//////////////////////////////////////////////////////
			// Swap out and wait for a signal from the IX Bus Unit
			// that the packet data is in the Receive FIFO Element
			//////////////////////////////////////////////////////
			ctx_wait(start_receive);
			*p_led = 2;


			//////////////////////////////////////////////////////
			// The packet is now in an RFIFO Element.  Read the
			// RVC_CNTL register to retrieve the control information 
			//
			// Note the use of a temporary register to perform read
			// due to transfer register issues.
			//////////////////////////////////////////////////////
			csr_read(&temp_csr, rcv_cntl, 1, ctx_swap);
			rcv_cmd = temp_csr;

			//; RCV_CNTL REGISTER FORMAT
			//; +-----+-----+-----+------+----+-----+-----+----+----+-----------+---+---+
			//; | msg |port |seq# |rxfail|err |elem2|elem1|1or2|seq | validbytes|EOP|SOP|
			//; |31:30|29:24|23:20|  19  | 18 |17:14|13:10| 9  | 8  |    7:2    | 1 | 0 |
			//; +-----+-----+-----+------+----+-----+-----+----+----+-----------+---+---+

			*p_led = 3;

			//////////////////////////////////////////////////////
			// Move the packet from the RFIFO Element to the
			// packet buffer in SDRAM
			//////////////////////////////////////////////////////

			////////////////////////////////////////////////////////
			// Take the element number from the RCV_CNTL register,
			// then multiply it by 8 (the number of quadwords per
			// element) to get the address of the FIFO Element
			////////////////////////////////////////////////////////
			rfifo_entry = (rcv_cmd>>10) & 0xF;
			dram_rfifo_read_ind.qword_addr = rfifo_entry * 8;
			*p_led = 4;

		//	sdram_r_fifo_read_ind(packet, 4, dram_rfifo_read_ind, queue_default, ctx_swap);

			*p_led = 5;

			//////////////////////////////////////////////////////
			// Format the packet descriptor
			//   - Take quadword count, byte count, EOP and SOP flags,
			//     and port number from the RCV_CNTL
			// Write descriptor to SRAM
			// Signal the Transmit thread to process the packet
			// Increment the packet counter
			//////////////////////////////////////////////////////

			//; RCV_CNTL REGISTER FORMAT
			//; +-----+-----+-----+------+----+-----+-----+----+----+-----------+---+---+
			//; | msg |port |seq# |rxfail|err |elem2|elem1|1or2|seq | validbytes|EOP|SOP|
			//; |31:30|29:24|23:20|  19  | 18 |17:14|13:10| 9  | 8  |    7:2    | 1 | 0 |
			//; +-----+-----+-----+------+----+-----+-----+----+----+-----------+---+---+

			//; DESCRIPTOR FORMAT
			//; +-----+-------+---------+---+---+----+----+
			//; | res | num qw|num bytes|EOP|SOP|skip|port|
			//; | 31  | 15:13 |  12:10  | 9 | 8 | 7  |6:0 |
			//; +-----+-------+---------+---+---+----+----+
			temp_desc = rcv_cmd & 0xFF;	// EOP/SOP and valid bytes
			temp_desc = (temp_desc<<8) | ((rcv_cmd>>24)&0x3F); //add port info

			(*p_descriptor) = temp_desc;	//write descriptor to memory

			*p_led = 6;

			//At this point, signal transmit thread
			csr_fast_write(inter_thd_sig, 0x4);

			packet_count++; //increment packet count
	

			//now wait for signal from transmit thread
			//before getting another packet
			ctx_wait(inter_thread);

		} //while - go to start of receive loop

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

	}

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

} //receive3 main

⌨️ 快捷键说明

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