📄 h2.c
字号:
h2_write(PORT, port_no, PORT_MAXLEN, JUMBO_SIZE);
#else
h2_write(PORT, port_no, PORT_MAXLEN, 1536);
#endif
/* Set up flow control */
h2_setup_flow_control(port_no, link_mode);
h2_enable_exc_col_drop(port_no, 0);
/* set bit in analyzer receive mask */
h2_set_ana_recv_mask(port_no, 1);
}
vtss_update_masks();
}
static void use_rxclk_as_txclk (uchar port_no, uchar enable)
{
uchar dev;
uchar delay;
if ((port_no < 8) || (port_no > 15)) {
if ((h2_read(SYSTEM, 0, SYS_CHIPID) & 0xF0000000) < 0x20000000) {
if (port_no < 8) {
dev = port_no;
}
else {
dev = port_no - 8;
}
if (enable) {
h2_write(SYSTEM, 0, SYS_SGMII_TR_DBG, 0x6A8000EF | ((ulong) dev << 19));
for (delay = 0; delay < 10; delay++) {
/* delay */
}
h2_write(SYSTEM, 0, SYS_SGMII_TR_DBG, 0x6A820010 | ((ulong) dev << 19));
}
else {
h2_write(SYSTEM, 0, SYS_SGMII_TR_DBG, 0x6A820000 | ((ulong) dev << 19));
}
}
}
}
/* ************************************************************************ */
static void h2_setup_hdx_gaps (uchar port_no, uchar link_mode)
/* ------------------------------------------------------------------------ --
* Purpose : Setup half duplex gaps register according to link mode.
* Remarks : Please see main.h for a description of link_mode.
* Restrictions:
* See also :
* Example :
* ************************************************************************ */
{
if (link_mode == LINK_MODE_SPEED_10) {
h2_write_masked(PORT, port_no, PORT_MACHDXGAP, (ushort) (LCOLPOS) << 8 |
(RX_TX_IFG_2_10 << 4) | (RX_TX_IFG_1_10), 0x0FFF);
}
else {
h2_write_masked(PORT, port_no, PORT_MACHDXGAP, (ushort) (LCOLPOS) << 8 |
(RX_TX_IFG_2_100 << 4) | (RX_TX_IFG_1_100), 0x0FFF);
}
}
/* ************************************************************************ */
ulong h2_build_mac_config (uchar port_no, uchar link_mode)
/* ------------------------------------------------------------------------ --
* Purpose : Build a template for MACCONF register with tx clock, duplex
* mode, giga mode and interframe gap set according to link_mode
* parameter.
* Remarks : See main.h for a description of link_mode.
* Restrictions:
* See also :
* Example :
* ************************************************************************ */
{
port_no = port_no; /* keep compiler happy */
if (link_mode == LINK_MODE_FDX_10) {
return ((ulong) 0x00040003 | (TX_IPG_10 << 6));
}
else if (link_mode == LINK_MODE_HDX_10) {
return ((ulong) 0x80000003 | (TX_IPG_10 << 6));
}
else if (link_mode == LINK_MODE_FDX_100) {
return ((ulong) 0x00040002 | (TX_IPG_100 << 6));
}
else if (link_mode == LINK_MODE_HDX_100) {
return ((ulong) 0x80000002 | (TX_IPG_100 << 6));
}
else { /* 1000 FDX */
return ((ulong) 0x00060001 | (TX_IPG_1000 << 6));
}
}
#ifdef DISABLE_FRAME_AGING
/* *********************************************************************** */
void h2_disable_frame_aging (void)
/* ------------------------------------------------------------------------ --
* Purpose : Disable frame aging by writing 0 to TIMECMP register and
* take into account that there are time slots in which
* writing 0 won't work.
* Remarks :
* Restrictions: It may only be called during power-up phase right before
* call to h2_post_reset.
* See also :
* Example :
* ************************************************************************ */
{
uchar port_no;
uchar j;
h2_write(SYSTEM, 0, SYS_TIMECMP, 0); /* Disable aging of queued frames */
/*
** Set port 0 and 1 to loopback. And set masks, etc. to make a CPU frame
** sent out on port 0 be looped back on port 0 and forwarded to port 1.
*/
for (port_no = 0; port_no < 2; port_no++) {
h2_write_masked(PORT, port_no, PORT_ADVPORTM, 0x01, 0x01); /* loopback */
h2_write_masked(PORT, port_no, 0x18, 0x040000, 0x040000); /* loopback */
h2_write(PORT, port_no, PORT_MACCONF, 0x10070181);
}
h2_write(PORT, 0, PORT_TXUPDCFG, 0x06); /* Update CRC */
h2_write(PORT, 1, PORT_CNT_CTRL_CFG, 0x38200820); /* count tx drop in C_TX2 */
h2_write(ANALYZER, 0, ANA_LERNMASK, 0);
h2_write(ANALYZER, 0, ANA_UFLODMSK, 0x02);
h2_write(ANALYZER, 0, ANA_RECVMASK, 0x01);
h2_write(ANALYZER, 0, ANA_SRCMASKS + 0, 0x02);
h2_write(ANALYZER, 0, ANA_SRCMASKS + 1, 0x00);
/*
** Send a frame on port 0
*/
h2_write(PORT, 0, PORT_CPUTXDAT, (ulong) 64 << CPU_FRAME_LENGTH_BIT);
h2_write(PORT, 0, PORT_CPUTXDAT, 0x520);
for (j = 0; j < (((64 + 7) / 8) * 2); j++) {
h2_write(PORT, 0, PORT_CPUTXDAT, 0x12345678);
}
h2_write(PORT, 0, PORT_MISCFIFO, 0x01);
delay_1(3);
/* If the frame get dropped in the FIFO, TIMECMP must be set again. */
if (h2_read(PORT, 1, PORT_C_TX2) != 0) {
h2_write(SYSTEM, 0, SYS_TIMECMP, 0x3b9aca0);
delay_1(2);
h2_write(SYSTEM, 0, SYS_TIMECMP, 0);
}
/*
** restore changed registers apart from TIMECMP
*/
for (port_no = 0; port_no < 2; port_no++) {
h2_write_masked(PORT, port_no, PORT_ADVPORTM, 0x00, 0x01); /* reset loopback */
h2_write_masked(PORT, port_no, 0x18, 0x000000, 0x040000); /* reset loopback */
h2_write(PORT, port_no, PORT_MACCONF, 0x2004083c);
h2_write(PORT, port_no, PORT_C_RX0, 0x00); /* clear all counters */
}
h2_write(PORT, 0, PORT_TXUPDCFG, 0x00);
h2_write(PORT, 1, PORT_CNT_CTRL_CFG, 0x08200820);
h2_write(ANALYZER, 0, ANA_LERNMASK, ALL_PORTS);
h2_write(ANALYZER, 0, ANA_UFLODMSK, ALL_PORTS);
h2_write(ANALYZER, 0, ANA_RECVMASK, 0x00000000);
h2_write(ANALYZER, 0, ANA_SRCMASKS + 0, 0x1fffffe);
h2_write(ANALYZER, 0, ANA_SRCMASKS + 1, 0x1fffffd);
}
#endif
/* *********************************************************************** */
uchar h2_check (void) small
/* ------------------------------------------------------------------------ --
* Purpose : Check health of switch chip.
* Remarks : Returns 0, if chip is ok, otherwise <> 0.
* Restrictions:
* See also :
* Example :
* ************************************************************************ */
{
#if H2_ID_CHECK
if ((h2_read(SYSTEM, 0, SYS_CHIPID) & 0x0FFFFFFF) != EXPECTED_CHIPID) {
return 1;
}
#endif
return 0;
}
/* ************************************************************************ **
*
*
* Public register access functions (primarily for code space optimization)
*
*
*
* ************************************************************************ */
void h2_enable_rx_tx (uchar port_no)
{
/* remove load seed bit and set tx_en and rx_en bits */
h2_write_masked(PORT, port_no, PORT_MACCONF, 0x10010000, 0x18010000);
}
void h2_enable_exc_col_drop (uchar port_no, uchar drop_enable)
{
h2_write_bit(PORT, port_no, PORT_ADVPORTM, 6, !drop_enable);
}
/* ************************************************************************ **
*
*
* Help functions
*
*
*
* ************************************************************************ */
void vtss_update_masks(void)
{
uchar port_no;
port_bit_mask_t link_mask;
link_mask = phy_get_link_mask();
for (port_no = MIN_PORT; port_no < MAX_PORT; port_no++)
h2_write_masked(ANALYZER, 0, ANA_SRCMASKS + port_no, ~PORT_BIT_MASK(port_no) & link_mask, ALL_PORTS);
}
static void arbiter_discard (uchar port_no, uchar status)
{
h2_write_bit(ARBITER, 0, ARBDISC, port_no, status);
}
static void stop_reception (uchar port_no)
{
/* disable rx for the port */
h2_write_bit(PORT, port_no, PORT_MACCONF, 16, 0);
}
static uchar await_arbiter_empty (port_bit_mask_t port_mask)
{
start_timer(MSEC_500);
do {
if (((port_bit_mask_t) h2_read(ARBITER, 0, ARBEMPTY) & port_mask) == port_mask) {
return TRUE;
}
} while (!timeout());
return FALSE;
}
static void empty_arbiter (uchar port_no)
{
/* Stop reception of frames from port */
stop_reception(port_no);
/* set arbiter discard for the port */
arbiter_discard(port_no, 1);
/* Wait until arbiter empty for port */
(void) await_arbiter_empty(PORT_BIT_MASK(port_no));
/* clear arbiter discard for the port */
arbiter_discard(port_no, 0);
}
void h2_set_ana_recv_mask(uchar port_no, uchar status)
{
h2_write_bit(ANALYZER, 0, ANA_RECVMASK, port_no, status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -