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 + -
显示快捷键?