📄 h2txrx.c
字号:
/*
Copyright (c) 2002-2005 Vitesse Semiconductor Corporation "Vitesse".
All Rights Reserved. Unpublished rights reserved under the copyright laws
of the United States of America, other countries and international treaties.
The software is provided without a fee. Permission to use, copy, store and
modify, the software and its source code is granted. Permission to integrate
into other products, disclose, transmit and distribute the software in an
absolute machine readable format (e.g. HEX file) is also granted.
The source code of the software may not be disclosed, transmitted or
distributed without the written permission of Vitesse. The software and its
source code may only be used in products utilizing a Vitesse VSC73xx product.
This copyright notice must appear in any copy, modification, disclosure,
transmission or distribution of the software. Vitesse retains all ownership,
copyright, trade secret and proprietary rights in the software.
THIS SOFTWARE HAS BEEN PROVIDED "AS IS," WITHOUT EXPRESS OR IMPLIED WARRANTY
INCLUDING, WITHOUT LIMITATION, IMPLIED WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR USE AND NON-INFRINGEMENT.
*/
#include "common.h"
#include "hwconf.h"
#include "h2reg.h"
#include "h2io.h"
#include "h2.h"
#include "h2txrx.h"
#if LOOPBACK_TEST
#define __BASIC_TX_RX__
#endif
/* ************************************************************************ **
*
*
* Defines
*
*
*
* ************************************************************************ */
#define MIN_FRAME_SIZE 64
#define PADDING_PATTERN 0x55555555
/* ************************************************************************ **
*
*
* Typedefs and enums
*
*
*
* ************************************************************************ */
/* ************************************************************************ **
*
*
* Prototypes for local functions
*
*
*
* ************************************************************************ */
/* ************************************************************************ **
*
*
* Local data
*
*
*
* ************************************************************************ */
#ifdef __BASIC_TX_RX__
static data uchar cur_tx_port;
static data uchar cur_tx_pad_cnt;
static data ushort cur_rx_offset;
/* ************************************************************************ **
*
*
* Public data
*
*
*
* ************************************************************************ */
bit cpu_tx_congestion = FALSE;
/* ************************************************************************ */
bool h2_frame_received (void) small
/* ------------------------------------------------------------------------ --
* Purpose : Check if a frame has been forwarded to the CPU.
* Remarks : Returns TRUE if frame is ready, otherwise FALSE is returned.
* Restrictions:
* See also :
* Example : The following protocol must be used for reading a frame
* forwarded to the cpu:
* if h2_frame_received() {
* length = h2_rx_hdr(&frm_hdr);
* loop according to length {
* data_chunk = h2_rx_word();
* }
* h2_rx_ack();
* }
* ************************************************************************ */
{
return ((FPSTAT & 0x03) != 0);
}
/* ************************************************************************ */
ushort h2_rx_hdr (vtss_frm_hdr_t *frm_hdr_p) small
/* ------------------------------------------------------------------------ --
* Purpose : Read header of the frame forwarded to the cpu and extract
* header fields.
* Remarks : Frame length is returned. Additional header parameters
* are returned in the header structure.
* Restrictions: See h2_frame_received.
* See also :
* Example :
* ************************************************************************ */
{
ul_union_t tmp;
ushort frame_len;
cur_rx_offset = 0;
tmp.l = h2_rx_word();
frame_len = tmp.w[0] & 0x3FFF; /* bits 61:48 */
if (frm_hdr_p) {
frm_hdr_p->src_port = (tmp.b[2] >> 2) & 0x1f; /* bits 46:42*/
tmp.l = h2_rx_word();
}
return frame_len;
}
/* ************************************************************************ */
ulong h2_rx_word (void) small
/* ------------------------------------------------------------------------ --
* Purpose : Read a 32-bit chunk from CPU capture buffer.
* Remarks :
* Restrictions: See h2_frame_received.
* See also :
* Example :
* ************************************************************************ */
{
ulong tmp;
tmp = h2_read(CAPTURE, cur_rx_offset >> 8, cur_rx_offset & 0xff);
cur_rx_offset++;
return tmp;
}
/* ************************************************************************ */
void h2_rx_ack (void) small
/* ------------------------------------------------------------------------ --
* Purpose : Flush received frame from input queue.
* Remarks :
* Restrictions: See h2_frame_received.
* See also :
* Example :
* ************************************************************************ */
{
h2_write(CAPTURE, CAP_SUBBLK_STATUS, CAPREADP, 0);
}
/* ************************************************************************ */
void h2_tx_init (uchar port_no, ushort frame_len) small
/* ------------------------------------------------------------------------ --
* Purpose : Transfer frame header to tx queue.
* Remarks : port_no specifies switch port on which to send the frame.
* frame_len specifies the length of the frame in bytes.
* Restrictions:
* See also :
* Example : The following protocol must be used for sending a frame:
* h2_tx_init(port_no, length);
* loop according to length {
* h2_tx_word(data_chunk);
* }
* h2_tx_flush();
* ************************************************************************ */
{
cur_tx_port = port_no;
if (frame_len < MIN_FRAME_SIZE) {
cur_tx_pad_cnt = (MIN_FRAME_SIZE - frame_len) / 4;
}
else {
if (((frame_len + 3) / 4) & 0x01) {
cur_tx_pad_cnt = 1;
}
else {
cur_tx_pad_cnt = 0;
}
}
/*
** Insert internal frame header in tx buffer
*/
if (frame_len >= MIN_FRAME_SIZE) {
h2_tx_word((ulong) frame_len << CPU_FRAME_LENGTH_BIT);
}
else {
h2_tx_word((ulong) MIN_FRAME_SIZE << CPU_FRAME_LENGTH_BIT);
}
h2_tx_word(0x520);
}
/* ************************************************************************ */
void h2_tx_word (ulong w) small
/* ------------------------------------------------------------------------ --
* Purpose : Write a 32-bit chunk to transmit fifo.
* Remarks :
* Restrictions: See h2_tx_init
* See also :
* Example :
* ************************************************************************ */
{
uchar idata timeout;
/* If congestion, await recovery */
if (cpu_tx_congestion) {
return;
}
/* Write chunk */
h2_write(PORT, cur_tx_port, PORT_CPUTXDAT, w);
/*
** Await transfer
*/
timeout = 0;
while (( (ushort) h2_read(PORT, cur_tx_port, PORT_MISCSTAT) & 0x100) != 0) {
if (++timeout > 100) {
cpu_tx_congestion = TRUE;
break;
}
}
}
/* ************************************************************************ */
void h2_tx_flush (void) small
/* ------------------------------------------------------------------------ --
* Purpose : Possibly add padding and then flush frame from tx queue.
* Remarks :
* Restrictions: See h2_tx_init
* See also :
* Example :
* ************************************************************************ */
{
/* Add padding if needed */
while (cur_tx_pad_cnt-- > 0) {
h2_tx_word(PADDING_PATTERN);
}
/* If congestion occured, rewind */
if (cpu_tx_congestion) {
h2_write_bit(PORT, cur_tx_port, PORT_MISCFIFO, 1, 1); /* rewind */
cpu_tx_congestion = FALSE;
}
else {
/* Commit */
h2_write_bit(PORT, cur_tx_port, PORT_MISCFIFO, 0, 1);
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -