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

📄 phytsk.c

📁 Vitesse 24port gigabit Switch Source Code
💻 C
📖 第 1 页 / 共 3 页
字号:

        fix_data[port_no].mac_speed = fix_data[port_no].phy_speed;
        
        phy_state[port_no] = WAITING_FOR_LINK_SPECIAL_0;
        break;

    default:
        break;
    }
}




/* ************************************************************************ */
void phy_timer_10 (void)
/* ------------------------------------------------------------------------ --
 * Purpose     : Tick PHY timers. To be called every 10 msec (approximately).
 * Remarks     :
 * Restrictions: Don't call it from timer interrupt function.
 * See also    :
 * Example     :
 * ************************************************************************ */
{
    static uchar poll_phy_timer = 0;
    uchar port_no;
    if (++poll_phy_timer >= 10) {
        poll_phy_timer = 0;
        poll_phy_flag = TRUE;
    }

    for (port_no = MIN_PORT; port_no < MAX_PORT; port_no++) {
        if (fix_data[port_no].timer != 0) {
            fix_data[port_no].timer--;
        }
    }
}



/* ************************************************************************ */
uchar phy_get_link_state (uchar port_no)
/* ------------------------------------------------------------------------ --
 * Purpose     : Get (software) link state (up/down) for specified port.
 * Remarks     : Return TRUE if link is up, otherwise FALSE
 * Restrictions:
 * See also    :
 * Example     :
 * ************************************************************************ */
{
    if (TEST_PORT_BIT_MASK(port_no, &phy_link_up_mask)) {
        return TRUE;
    }

    return FALSE;
}

/* ************************************************************************ */
port_bit_mask_t phy_get_link_mask (void)
/* ------------------------------------------------------------------------ --
 * Purpose     : Get link state (up/down) for all ports.
 * Remarks     : Return bit mask where each bit represents a port.
 * Restrictions:
 * See also    :
 * Example     :
 * ************************************************************************ */
{
    port_bit_mask_t link_mask;
    uchar port_no;

    link_mask = 0;
    for (port_no = MIN_PORT; port_no < MAX_PORT; port_no++) {
        if (phy_get_link_state(port_no)) {
            WRITE_PORT_BIT_MASK(port_no, 1, &link_mask);
        }
    }
    return link_mask;
}


/* ************************************************************************ **
 *
 *
 * Support functions
 *
 *
 *
 * ************************************************************************ */

static uchar phy_init_state (uchar port_no)
{

    if (phy_map(port_no)) {
        return SET_UP_SPEED_MODE_ON_PHY;
    }
    else {
        return PORT_DISABLED;
    }
}


static void do_link_up (uchar port_no)
{
    vtss_update_masks();
    port_no = port_no; /* keep compiler happy */
}

static void do_link_down (uchar port_no)
{
    WRITE_PORT_BIT_MASK(port_no, 0, &phy_link_up_mask);

    if (phy_map(port_no)) {
        /* Do any set-up of PHY due to link going down */
        phy_do_link_down_settings(port_no);
    }


    h2_setup_port(port_no, LINK_MODE_DOWN);


}

/* 
** Return link mode
** bit 1:0 = 00:   10 Mbit/s
** bit 1:0 = 01:  100 Mbit/s
** bit 1:0 = 10: 1000 Mbit/s
**
** bit 4 = 0: half duplex
** bit 4 = 1: full duplex
**
** bit 5 = 0: link partner doesn't support pause frames
** bit 5 = 1: link partner does support pause frames
*/
static uchar get_link_mode (uchar port_no)
{
    uchar link_mode;

    link_mode = get_speed_and_fdx(port_no);

    /* check if link partner supports pause frames */
    if (phy_read(port_no, 5) & 0x0400) {
        link_mode |= LINK_MODE_PAUSE_MASK;
    }

    return link_mode;
}
static uchar get_speed_and_fdx (uchar port_no)
{
    uchar speed_fdx_mode;
    ushort reg_val;
    phy_id_t phy_id;


    phy_read_id(port_no, &phy_id);

    if (phy_id.vendor != PHY_VENDOR_VTSS) {
        /* Get speed and duplex mode into speed_fdx_mode variable */
        PHY_READ_SPEED_AND_FDX(port_no, reg_val, speed_fdx_mode);
        return speed_fdx_mode;
    }

    /* Get info about speed and duplex mode from PHY reg. 28 */ 
    reg_val = phy_read(port_no, 28);

    /* set speed field (bit 1:0) = bit 4:3 of PHY reg. */
    speed_fdx_mode = ((uchar) reg_val >> 3) & 0x03;

    /* update full duplex bit */
    if (reg_val & 0x20) {
        speed_fdx_mode |= LINK_MODE_FDX_MASK;
    }

    return speed_fdx_mode;
}



#if TRANSIT_VERIPHY

/* ************************************************************************ **
 *
 *
 * Power up VeriPHY for unmanaged
 *
 *
 *
 * ************************************************************************ */

#define SCAN_LED_TIME 80

#define PHY_REG_27_LED_CONFIG 0x0064

void set_scan_led (uchar port_no)
{
    phy_write_led_mode_reg(port_no, 0xeeef);  /* turn on LED 0 */
}

void set_ok_led (uchar port_no)
{
    phy_write_led_mode_reg(port_no, 0xeeef); /* turn on LED 0 */
}

void set_error_led (uchar port_no)
{
    phy_write_led_mode_reg(port_no, 0xeefe); /* turn on LED 1 */
}

void set_led_normal (uchar port_no)
{
    phy_write_led_mode_reg(port_no, PHY_LED_MODE);
}

void reset_leds (uchar port_no)
{
    phy_write_led_mode_reg(port_no, 0xeeee);
}


/* ************************************************************************ */
void phy_veriphy_all (void)
/* ------------------------------------------------------------------------ --
 * Purpose     : 
 * Remarks     :
 * Restrictions:
 * See also    :
 * Example     :
 * ************************************************************************ */
{
    uchar result;
    uchar port_no;
    port_bit_mask_t error_flags;
    port_bit_mask_t active_flags;
    veriphy_parms_t xdata veriphy_parms [MAX_PORT];
    uchar max_delay;
    uchar led_port_no;
    ushort idata led_timer;
    ushort idata delta_time;


    /*
    ** Turn off LEDs on all ports and start veriphy on all ports
    */
    for (port_no = MIN_PORT; port_no < MAX_PORT; port_no++) {
        reset_leds(port_no);

        veriphy_start(port_no, &veriphy_parms[port_no]);
    }


    /*
    ** Run through ports/PHYs one at a time
    */
    error_flags = 0;
    EA = 0;
    led_timer = tick_count;
    EA = 1;
    led_port_no = MIN_PORT;
    set_scan_led(led_port_no);
    active_flags = ALL_PORTS;

    while (active_flags || (led_port_no < MAX_PORT)) {
        max_delay = 0;
        for (port_no = MIN_PORT; port_no < MAX_PORT; port_no++) {                
            if (TEST_PORT_BIT_MASK(port_no, &active_flags)) {

                while ((result = veriphy_run(port_no, &veriphy_parms[port_no])) == VERIPHY_CONTINUE) { 
                }
                if (result & VERIPHY_DONE_MASK) {
                    WRITE_PORT_BIT_MASK(port_no, 0, &active_flags);
                    if (result != VERIPHY_DONE_OK) {
                        WRITE_PORT_BIT_MASK(port_no, 1, &error_flags);
                    }
                }
                else {
                    if (result > max_delay) {
                        max_delay = result;
                    }                
                }
            }
            /*
            ** Pretend sequential progress on LEDs
            */
            EA = 0;
            delta_time = tick_count - led_timer;
            EA = 1;
            if (delta_time > SCAN_LED_TIME) {
                if (led_port_no < MAX_PORT) {
                    reset_leds(led_port_no);
                    led_port_no++;
                    if (led_port_no < MAX_PORT) {
                        set_scan_led(led_port_no);
                    }
                }
                EA = 0;
                led_timer = tick_count;
                EA = 1;
            }
        }
        if (max_delay > 0) {
            delay(max_delay + 1);
        }
    }


    /*
    ** Indicate results on LEDs for 5 seconds
    */
    for (port_no = MIN_PORT; port_no < MAX_PORT; port_no++) {
        if (TEST_PORT_BIT_MASK(port_no, &error_flags)) {
            set_error_led(port_no);
        }
        else {
            set_ok_led(port_no);
        }
    }
    /* Wait 5 seconds */
    delay(250);
    delay(250);

    /*
    ** Set LEDs back to normal
    */
    for (port_no = MIN_PORT; port_no < MAX_PORT; port_no++) {
        set_led_normal(port_no);

        veriphy_done(port_no, &veriphy_parms[port_no]);
    }
    /* Restore speed on MIIM back to normal */
//    h2_write(MIIM, 0, MIIMPRES, 0x50);

}
#endif

static void phy_fix_setup(uchar port_no)
{
    fix_data[port_no].phy_speed = 0xff;
    fix_data[port_no].mac_speed = 0xff;
    fix_data[port_no].iteration = 0;

    phy_write_masked(port_no, 4, 0x8000, 0x8000);

    phy_page_tr(port_no);

    phy_write(port_no, 16, 0xa68c);
    phy_write_masked(port_no, 17, 0x10, 0x10);
    phy_write(port_no, 16, 0x868c);

    phy_write(port_no, 16, 0xa688);
    phy_write_masked(port_no, 17, 0x0004, 0x000c);
    phy_write(port_no, 16, 0x8688);

    phy_write(port_no, 16, 0xa686);
    phy_write_masked(port_no, 17, 0x20, 0x20);
    phy_write(port_no, 16, 0x8686);
    

    phy_page_std(port_no);

}

static ushort phy_epg_data (uchar port_no)
{
    switch(port_no) {
    case 0:
    case 7:
    case 19:
        return 0xdd3a;
        break;
        
    case 4:
    case 16:
    case 23:
        return 0x5aa5;
        break;
        
    case 5:
    case 6:
    case 17:
    case 18:
        return 0x5da2;
        break;
        
    default:
        return 0xdd3a;
        break;
    }
}

static uchar phy_epg_done (uchar port_no)
{
        if(fix_data[port_no].iteration >= 1) {
            return TRUE;
        } else {
            return FALSE;
        }
}

static void phy_epg_on (uchar port_no)
{
    phy_page_ext(port_no);

        if(fix_data[port_no].iteration == 1) {
            delay_1(5);
            phy_write(port_no, 0x1d, 0xa002);
            phy_write(port_no, 0x1d, 0xe002);
        } else {
            delay_1(5);
            phy_write(port_no, 0x1e, phy_epg_data(port_no));
            phy_write(port_no, 0x1d, 0xa000);
            phy_write(port_no, 0x1d, 0xe000);
        }
    phy_page_std(port_no);
}

static void phy_epg_restart (uchar port_no)
{
    phy_page_ext(port_no);
    phy_write(port_no, 0x1d, 0xa000);
    phy_write(port_no, 0x1d, 0xe000);
    phy_page_std(port_no);
}


static void phy_epg_off(uchar port_no)
{
    phy_page_ext(port_no);
    phy_write(port_no, 0x1d, 0x0040);

⌨️ 快捷键说明

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