⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 phydrv.c

📁 Vitesse 24port gigabit Switch Source Code
💻 C
📖 第 1 页 / 共 3 页
字号:
 * Remarks     :
 * Restrictions:
 * See also    :
 * Example     :
 * ************************************************************************ */
{
    phy_id_t phy_id;


    /* Possibly disable echo-mode on PHY when running half-duplex at 10M */
    if ((link_mode & (LINK_MODE_SPEED_MASK | LINK_MODE_FDX_MASK)) == LINK_MODE_SPEED_10) {
        PHY_DISABLE_ECHO_MODE(port_no);
    }
    else {
        PHY_ENABLE_ECHO_MODE(port_no);
    }

    /* Read PHY id to determine action */
    phy_read_id(port_no, &phy_id);

    /* Possibly reconfigure receiver if speed is 1G */
    if ((link_mode & LINK_MODE_SPEED_MASK) == LINK_MODE_SPEED_1000) {

        if ((phy_id.family == PHY_FAMILY_VTSS_8538) ||
            (phy_id.family == PHY_FAMILY_VTSS_8224) ||
            (phy_id.family == PHY_FAMILY_VTSS_7390)) {

            phy_receiver_reconfig(port_no);
        }

        if (phy_id.family == PHY_FAMILY_VTSS_8538) {

            phy_page_tp(port_no);
            phy_write_masked(port_no, 20, 0x1400, 0x1f00);
            phy_write_masked(port_no, 20, 0x1600, 0x1f00);
            phy_page_std(port_no);
        }
    }


    if ((link_mode & LINK_MODE_SPEED_MASK) == LINK_MODE_SPEED_10) {
        if (phy_id.family == PHY_FAMILY_VTSS_7390) {
            
            phy_page_tp(port_no);
            phy_write_masked(port_no, 20, 0x1400, 0x1f00);
            phy_write_masked(port_no, 20, 0x1300, 0x1f00);
            phy_page_std(port_no);
        }
    }

#if VTSS_8538
    if ((phy_id.family == PHY_FAMILY_VTSS_8538) && (phy_id.revision == 0)) {

        uchar rx_tr_lock;

        phy_page_tr(port_no);
        phy_write(port_no, 16, 0xa60c);
        phy_write(port_no, 16, 0xa60c);
        rx_tr_lock = (phy_read(port_no, 17) >> 3) & 0x01;
        if (!rx_tr_lock) {
            phy_write(port_no, 17, 0x0010);
            phy_write(port_no, 16, 0x8604);
            phy_write(port_no, 17, 0x00df);
            phy_write(port_no, 16, 0x8600);
            phy_write(port_no, 17, 0x00ff);
            phy_write(port_no, 16, 0x8600);
            phy_write(port_no, 17, 0x0000);
            phy_write(port_no, 16, 0x8604);
            phy_write(port_no, 16, 0xa60c);
            phy_write(port_no, 16, 0xa60c);
            rx_tr_lock = (phy_read(port_no, 17) >> 3) & 0x01;
            if (!rx_tr_lock) {
            }
        }
        phy_page_std(port_no);
    }

    if (phy_id.model == PHY_MODEL_VTSS_8558) {
        uchar fiber;

        phy_page_ext(port_no);
        fiber = ((phy_read(port_no, 20) & 0x00c0) == 0x0080);
        phy_page_std(port_no);
        if (fiber) {
            phy_write(port_no, 29, PHY_LED_MODE_SFP);
        }
        else {
            phy_write(port_no, 29, PHY_LED_MODE);
        }
    }
#endif

    sgmii_lock_seq(port_no);
}

/* ************************************************************************ */
void phy_do_link_down_settings (uchar port_no)
/* ------------------------------------------------------------------------ --
 * Purpose     : Do any PHY settings after link transition to down.
 * Remarks     :
 * Restrictions:
 * See also    :
 * Example     :
 * ************************************************************************ */
{    


    phy_id_t phy_id;

    phy_read_id(port_no, &phy_id);

    if ((phy_id.family == PHY_FAMILY_VTSS_8538) ||
        (phy_id.family == PHY_FAMILY_VTSS_8224) ||
        (phy_id.family == PHY_FAMILY_VTSS_7390)) {

        phy_receiver_init(port_no);
    }

    if ((phy_id.family == PHY_FAMILY_VTSS_8538) ||
        (phy_id.family == PHY_FAMILY_VTSS_7390)) {
        phy_page_tp(port_no);
        phy_write_masked(port_no, 20, 0x1400, 0x1f00);
        phy_write_masked(port_no, 20, 0x1400, 0x1f00);
        phy_page_std(port_no);
    }
}

static void phy_receiver_init (uchar port_no)
{
    phy_page_tp(port_no);
    phy_write_masked(port_no, 12, 0x0200, 0x0300);
    phy_page_std(port_no);
}
static void phy_receiver_reconfig (uchar port_no)
{
    uchar vga_state_a;

    phy_page_tr(port_no);
    phy_write(port_no, 16, 0xaff0);
    vga_state_a = (phy_read(port_no, 17) >> 4) & 0x01f;
    if ((vga_state_a < 16) || (vga_state_a > 20)) {
        phy_page_tp(port_no);
        phy_write_masked(port_no, 12, 0x0000, 0x0300);
    }
    phy_page_std(port_no);
}

#if TRANSIT_VERIPHY
/* ************************************************************************ */
void phy_write_led_mode_reg (uchar port_no, ushort reg_value)
/* ------------------------------------------------------------------------ --
 * Purpose     : 
 * Remarks     :
 * Restrictions:
 * See also    :
 * Example     :
 * ************************************************************************ */
{
    if (port_no < 8 || port_no > 15) {
        phy_write(port_no, 29, reg_value);
    }
    else {
        phy_write(port_no, 27, reg_value);
    }
}
#endif /* TRANSIT_VERIPHY */

/* ************************************************************************ */
uchar sgmii_tr_read (uchar port_no, uchar reg_no)
/* ------------------------------------------------------------------------ --
 * Purpose     : Read a SGMII token-ring register.
 * Remarks     : port_no: The port number
 *               reg_no: the token-ring register number (0-7).
 * Restrictions:
 * See also    :
 * Example     :
 * ************************************************************************ */
{
    uchar dev;

    if ((port_no < 8) || (port_no > 15)) {
        if (port_no < 8) {
            dev = port_no;
        }
        else {
            dev = port_no - 8;
        }

        h2_write_masked(SYSTEM, 0, SYS_SGMII_TR_DBG, 
                        0x02000000 | ((ulong) dev << 19) | ((ulong) reg_no << 16), ~0xfc000000);

        sgmii_tr_await_completed();

        return ((ushort) h2_read(SYSTEM, 0, SYS_SGMII_TR_DBG) >> 8);
    }
    else {
        return 0;
    }
}

/* ************************************************************************ */
void sgmii_tr_write (uchar port_no, uchar reg_no, uchar value)
/* ------------------------------------------------------------------------ --
 * Purpose     : Write to a SGMII token-ring register.
 * Remarks     : port_no: The port number
 *               reg_no: the token-ring register number (0-7).
 *               value: value to be written.
 * Restrictions:
 * See also    :
 * Example     :
 * ************************************************************************ */
{
    uchar dev;

    if ((port_no < 8) || (port_no > 15)) {
        if (port_no < 8) {
            dev = port_no;
        }
        else {
            dev = port_no - 8;
        }

        h2_write_masked(SYSTEM, 0, SYS_SGMII_TR_DBG, 
                        0x02800000 | ((ulong) dev << 19) | ((ulong) reg_no << 16) | value, ~0xfc000000);

        sgmii_tr_await_completed();
    }
}


/* ************************************************************************ */
static void sgmii_tr_await_completed (void)
/* ------------------------------------------------------------------------ --
 * Purpose     : Await completion of a SGMII token-ring command.
 * Remarks     :
 * Restrictions:
 * See also    : sgmii_tr__read and sgmii_tr_write
 * Example     :
 * ************************************************************************ */
{
    ushort timeout;

    timeout = 0;
    while ((h2_read(SYSTEM, 0, SYS_SGMII_TR_DBG) & 0X02000000) != 0) {
        if (++timeout >= 1000) {
            break;
        }
    }
}

/* ************************************************************************ */
static void phy_await_completed (uchar miim_no) small
/* ------------------------------------------------------------------------ --
 * Purpose     : Await completion of a MIIM command.
 * Remarks     :
 * Restrictions:
 * See also    : phy_read and phy_write
 * Example     :
 * ************************************************************************ */
{
    /* wait until data ready or timeout */
    start_timer(MSEC_50);
    while (((uchar) h2_read(MIIM, miim_no, MIIMSTAT) & MIIM_COMPLETED_MASK) != 0) {
        if (timeout()) {
            set_fatal_error(MIIM_FAILURE);
            break;
        }
    }
}

void phy_page_ext (uchar port_no)
{
    phy_write(port_no, 31, 1);
}

void phy_page_tr (uchar port_no)
{
    phy_write(port_no, 31, TR_PAGE_CODE);
}

void phy_page_tp (uchar port_no)
{
    phy_write(port_no, 31, TP_PAGE_CODE);
}

void phy_page_std (uchar port_no)
{
    phy_write(port_no, 31, 0);
}

#ifdef __PHY_RESET__
static void assert_reset (uchar port_no)
{
    uchar timeout;

    phy_suspend_10_100_fix(port_no);

    phy_write(port_no, 0, 0x8000);
    delay_1(2); /* wait 1-2 msec before accessing registers */
    timeout = 0;
    while (phy_read(port_no, 0) & 0x8000) {
        if (++timeout > 200) {
            break; /* should not occur */
        }
        delay_1(1);
    }
}
#endif /* __PHY_RESET__ */

#if TRANSIT_VERIPHY
/* ************************************************************************ **
 *
 *
 * Functions needed for VeriPHY
 *
 *
 *
 * ************************************************************************ */

uchar data tr_raw_data [3];

void phy_write_ext (uchar port_no, uchar reg, ushort val)
{
    phy_page_ext(port_no);
    phy_write(port_no, reg, val);
    phy_page_std(port_no);
}

ushort phy_read_ext (uchar port_no, uchar reg)
{
    ushort tmp;

    phy_page_ext(port_no);
    tmp = phy_read(port_no, reg);
    phy_page_std(port_no);
    return tmp;
}

void phy_write_tp_bit (uchar port_no, uchar tp_reg_no, uchar bit_no, uchar bit_val)
{
    ushort bit_mask;

    bit_mask = bit_mask_16(bit_no);
    phy_page_tp(port_no);
    if (bit_val) {
        phy_write_masked(port_no, tp_reg_no, bit_mask, bit_mask);
    }
    else {
        phy_write_masked(port_no, tp_reg_no, 0, bit_mask);
    }
    phy_page_std(port_no);
}

void  phy_read_tr (uchar port_no, ushort ctrl_word)
{
    phy_page_tr(port_no);

//    SmiWrite(phy, 16, (5 << 13) | TrSubchanNodeAddr);
    phy_write(port_no, 16, (5 << 13) | ctrl_word);
    tr_raw_data[0] = phy_read(port_no, 18);                    /* high part (1 byte) */
    (*((ushort *) (&tr_raw_data[1]))) = phy_read(port_no, 17); /* low part (2 bytes) */
    phy_page_std(port_no);
}

void phy_write_tr (uchar port_no, ushort ctrl_word)
{
    phy_page_tr(port_no);
    phy_write(port_no, 18, tr_raw_data[0]);   /* high part */
    phy_write(port_no, 17, MK_USHORT(tr_raw_data[1], tr_raw_data[2]));  /* low part */

//    SmiWrite(phy, 16, (4 << 13) | TrSubchanNodeAddr);
    phy_write(port_no, 16, (4 << 13) | ctrl_word);
    phy_page_std(port_no);
}
#endif






⌨️ 快捷键说明

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