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