📄 phytsk.c
字号:
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 + -