📄 miiphy.c
字号:
highvideo();
cprintf ("INVALID PARAMETER: Duplex mode '%c'. Using Half duplex ('H').",duplex);
delay(3000);
printf("\r \r");
duplex = 'H';
}
if ((speed != 100) && (speed != 10))
{
textcolor(YELLOW+BLINK);
highvideo();
cprintf ("INVALID PARAMETER: Speed %d. Using 100 Mbps.",speed);
delay(3000);
printf("\r \r");
speed = 100;
}
if (PhyAddrRead && (Address > 31) )
{
textcolor(YELLOW+BLINK);
highvideo();
cprintf ("INVALID PARAMETER: PHY Address %d. Autodetecting.",Address);
delay(3000);
printf("\r \r");
PhyAddrRead = 0;
}
// Verify MAC is present
if(!DetectMAC())
{
textcolor(YELLOW);
highvideo();
cprintf("\n\r\n\rUNRECOVERABLE ERROR: Could not find MAC. Cannot access PHY.\n\r");
cprintf(" Try the /P=p option to specify the MAC IO address\n\r\n\r");
exit(1);
}
//Setting the AUI Select Bit for 91C110 PCMCIA Design. 11/23/99 PG
if(ositech)
{
outword(BANKSEL,1);
data = inword(BANKSEL);
// cprintf("\n\rData at Bank Select Register = %Xh",data );
// data = inword(port);
// cprintf("\n\rData at Config Register = %Xh",data );
outword(port ,data | 0x0100);
// data = inword(port);
// cprintf("\n\rData at Config Register = %Xh",data );
}
if (MACType == 'F') outword(BANKSEL, 3); // Select Bank 3
if (!PhyAddrRead)
{
PHYAdd = DetectPHY();
if (PHYAdd > 31)
{
textcolor(YELLOW);
highvideo();
cprintf("\n\r\n\rUNRECOVERABLE ERROR: PHY is not present or not supported\n\r\n\r");
exit(1);
}
}
else
{
unsigned int PhyId1, PhyId2;
PHYAdd = (unsigned char) Address;
PhyId1 = PHYAccess(PHYAdd, PHY_ID1, OPRead, 0);
PhyId1 = PHYAccess(PHYAdd, PHY_ID1, OPRead, 0);
PhyId2 = PHYAccess(PHYAdd, PHY_ID2, OPRead, 0);
PhyId2 = PHYAccess(PHYAdd, PHY_ID2, OPRead, 0);
OUI = (((unsigned long) PhyId1) << 6) | ((PhyId2 & 0xfc00) >> 10);
Model = (unsigned char) ( (PhyId2 & 0x03f0) >> 4 );
Revision = (unsigned char) (PhyId2 & 0x000f);
}
// Display PHY IDs
textcolor(CYAN);
highvideo();
cprintf("Information for PHY accessed thru");
if (MACType == 'F')
cprintf(" FEAST ");
else
cprintf(" EPIC ");
cprintf("family type MAC at IO = %04Xh\n\r", port);
textcolor(WHITE);
switch (OUI)
{
case PHY_OUI_QSI:
printf("PHY OUI = %06lX (QSI).",OUI);
break;
case PHY_OUI_TDK:
printf("PHY OUI = %06lX (TDK).",OUI);
break;
case PHY_OUI_MITELSMSC:
printf("PHY OUI = %06lX (MITEL/SMSC180).",OUI);
break;
case PHY_OUI_NATIONAL:
printf("PHY OUI = %06lX (NATIONAL).",OUI);
break;
case PHY_OUI_SEEQSMSC:
printf("PHY OUI = %06lX (SEEQ/SMSC183).", OUI);
break;
default:
printf("PHY OUI = %06lX (UNKNOWN).",OUI);
break;
}
printf(" PHY Model = %02X. PHY Revision = %02X\n\r", Model, Revision);
printf("PHY Address = %02Xh ",PHYAdd);
if(PhyAddrRead)
printf("(Forced)\n\r");
else
printf("(Autodetected)\n\r");
//Setup NV_CONTROL for the cardbus card.
if(OUI == PHY_OUI_TDK) outport(NV_CONTROL, 0x7c03);
if (ForcedSpeed || ForcedDuplex || NWAY)
{
// Save Register 0.
if (OUI == PHY_OUI_TDK) PHYAccess(PHYAdd,PHY_CR,OPRead,0);
PHYConfig = PHYAccess(PHYAdd,PHY_CR,OPRead,0);
if(OUI == PHY_OUI_TDK)
{
if(NWAY) outport(MIICFG, 0x0012); // Set ENABLE_694
//if using EPIC, Hardware Reset the PHY from the MAC
outport(CONTROL, inport(CONTROL) | 0x4000);
delay(1);
outport(CONTROL, inport(CONTROL) & (~0x4000));
delay(1);
}
// Reset PHY
PHYAccess(PHYAdd,PHY_CR,OPWrite,PHY_CR_Reset);
if(OUI == PHY_OUI_TDK)
PHYAccess(PHYAdd,PHY_CR,OPWrite,PHY_CR_Reset);
for (i=0;i<500;i++)
{
if(OUI == PHY_OUI_TDK) PHYAccess(PHYAdd,PHY_CR,OPRead,0);
if (PHYAccess(PHYAdd,PHY_CR,OPRead,0) & PHY_CR_Reset)
{
delay(1);
}
else break;
}
if (i == 500)
{
textcolor(YELLOW);
highvideo();
cprintf("\n\r\n\rUNRECOVERABLE ERROR: Could not reset PHY\n\r\n\r");
exit(1);
}
}
// Write selected configuration to the PHY and verify it by reading back
if(ForcedSpeed || ForcedDuplex)
{
PHYConfig &= 0x2100;
if(ForcedDuplex) PHYConfig &= 0xFEFF;
if(ForcedSpeed) PHYConfig &= 0xDFFF;
if (speed == 100) PHYConfig |= 0x2000;
if (duplex == 'F') PHYConfig |= 0x0100;
if (OUI == PHY_OUI_TDK) PHYAccess(PHYAdd,0,OPWrite,PHYConfig);
PHYAccess(PHYAdd,0,OPWrite,PHYConfig);
// Do we need to adjust the Carrier sense on full duplex FEAST issue ?
if ((duplex == 'F') && (MACType == 'F') && (OUI == PHY_OUI_MITELSMSC))
{
PHYAccess(PHYAdd,0x18,OPWrite, 0x0020 | PHYAccess(PHYAdd, 0x18,OPRead,0 ));
}
delay(50);
if (OUI == PHY_OUI_TDK) PHYConfig2 = PHYAccess(PHYAdd,0,OPRead,0);
PHYConfig2 = PHYAccess(PHYAdd,0,OPRead,0);
if (PHYConfig != PHYConfig2)
{
textcolor(YELLOW);
highvideo();
cprintf("\n\r\n\rUNRECOVERABLE ERROR: Read %04Xh after writing %04Xh to PHY Control Register\n\r\n\r");
exit(1);
}
}
if(NWAY)
{
// Set Advertising Register for all 10/100 and Half/Full combinations
if (OUI == PHY_OUI_TDK) PHYConfig = PHYAccess(PHYAdd, 4, OPRead, 0);
PHYConfig = PHYAccess(PHYAdd, 4, OPRead, 0);
PHYConfig |= 0x01e0;
PHYAccess(PHYAdd, 4, OPWrite, PHYConfig);
if (OUI == PHY_OUI_TDK) PHYAccess(PHYAdd, 4, OPWrite, PHYConfig);
// Start NWAY
PHYAccess(PHYAdd,0,OPWrite,0x0000); // National PHY requires clear before set NWAY enable.
PHYAccess(PHYAdd,0,OPWrite,0x1200);
if (OUI == PHY_OUI_TDK) PHYAccess(PHYAdd,0,OPWrite,0x1200);
// Wait for completion
textcolor(YELLOW+BLINK);
highvideo();
cprintf("\n\rPerforming NWAY (Advertising capable of all 10/100 & H/D modes)");
//DBG
//printf("\n\r");
for (i=0;i<NWAY_TIMEOUT;i++)
{
delay(1000);
cprintf(".");
PHYConfig = PHYAccess(PHYAdd, 1, OPRead, 0);
PHYConfig2 = PHYAccess(PHYAdd, 1, OPRead, 0);
if (PHYConfig != PHYConfig2) continue; // Value is not stable
if (PHYConfig & 0x0010) continue; // Remote Fault
if ((PHYConfig == 0x0000) || (PHYConfig == 0xffff)) continue; // invalid value
if (PHYConfig & 0x0020) break;
}
textcolor(WHITE);
printf("\r \r");
// Now read the results of the NWAY.
if (OUI == PHY_OUI_TDK) PHYConfig = PHYAccess(PHYAdd, 5, OPRead, 0);
PHYConfig = PHYAccess(PHYAdd, 5, OPRead, 0);
if (PHYConfig != 0)
{
// Got real NWAY information here
strcpy(report, "ANLPA");
if (PHYConfig & 0x0180)
speed = 100;
else
speed = 10;
if (PHYConfig & 0x0140)
duplex = 'F';
else
duplex = 'H';
}
else
{
// ANLPA was 0 so NWAY did not complete or is not reported fine.
// Get the info from propietary regs or from the control register.
strcpy(report, "Proprietary Status");
switch (OUI)
{
case PHY_OUI_NATIONAL:
PHYConfig = PHYAccess(PHYAdd, PHY_NATIONAL_PAR, OPRead, 0);
if (PHYConfig & PHY_NATIONAL_PAR_DUPLEX)
duplex = 'F';
else
duplex = 'H';
if (PHYConfig & PHY_NATIONAL_PAR_SPEED_10)
speed = 10;
else
speed = 100;
break;
case PHY_OUI_TDK:
PHYConfig = PHYAccess(PHYAdd, PHY_TDK_DIAG, OPRead, 0);
PHYConfig = PHYAccess(PHYAdd, PHY_TDK_DIAG, OPRead, 0);
if(
(
(Revision < 7) &&
((PHYConfig & 0x300) == 0x300)
)
||
(
(Revision >= 7) &&
(PHYConfig & PHY_TDK_DIAG_RATE)
)
)
speed = 100;
else
speed = 10;
if ((Revision >= 7) && (PHYConfig & PHY_TDK_DIAG_DUPLEX))
duplex = 'F';
else
duplex = 'H';
break;
case PHY_OUI_QSI:
PHYConfig = PHYAccess(PHYAdd, PHY_QSI_BASETX, OPRead, 0);
PHYConfig &= PHY_QSI_BASETX_OPMODE_MASK;
if(
(PHYConfig & PHY_QSI_BASETX_OPMODE_10FD) ||
(PHYConfig & PHY_QSI_BASETX_OPMODE_100FD)
)
duplex = 'F';
else
duplex = 'H';
if(
(PHYConfig & PHY_QSI_BASETX_OPMODE_100HD) ||
(PHYConfig & PHY_QSI_BASETX_OPMODE_100FD)
)
speed = 100;
else
speed = 10;
break;
case PHY_OUI_SEEQSMSC:
PHYConfig = PHYAccess(PHYAdd, PHY_SEEQ_STATUS_OUTPUT, OPRead, 0);
if (PHYConfig & PHY_SEEQ_DPLX_DET)
duplex = 'F';
else
duplex = 'H';
if (PHYConfig & PHY_SEEQ_SPD_DET)
speed = 100;
else
speed = 10;
break;
default:
strcpy(report, "Command");
PHYConfig = PHYAccess(PHYAdd, 0, OPRead, 0);
if (PHYConfig & 0x2000)
speed = 100;
else
speed = 10;
if (PHYConfig & 0x0100)
duplex = 'F';
else
duplex = 'H';
}
}
// Do we need to adjust the Carrier sense on full duplex FEAST issue ?
if ((duplex == 'F') && (MACType == 'F') && (OUI == PHY_OUI_MITELSMSC))
{
PHYAccess(PHYAdd,0x18,OPWrite, 0x0020 | PHYAccess(PHYAdd, 0x18,OPRead,0 ));
}
textcolor(CYAN);
highvideo();
cprintf("PHY Configuration reported by PHY's %s Register:\n\r",report);
textcolor(BLINK + YELLOW);
if (i == NWAY_TIMEOUT)
cprintf("NWAY Timeout ! ");
else
cprintf("NWAY Complete ! ");
textcolor(WHITE);
textcolor(WHITE);
}
if(offset != 0xffff)
{
if (OUI == PHY_OUI_TDK) PHYAccess(PHYAdd, (unsigned char) offset, OPWrite, data);
PHYAccess(PHYAdd, (unsigned char) offset, OPWrite, data);
}
// Report configuration reported on the status register
if (!NWAY)
{
textcolor(CYAN);
highvideo();
if (OUI == PHY_OUI_MITELSMSC)
strcpy (report,"Command");
else
strcpy (report,"Proprietary Status");
cprintf("\n\rPHY Configuration reported by PHY's %s Register:\n\r", report);
textcolor(WHITE);
/* if (OUI == PHY_OUI_TDK) PHYConfig = PHYAccess(PHYAdd, 0, OPRead, 0);
PHYConfig = PHYAccess(PHYAdd, 0, OPRead, 0);
if (PHYConfig & 0x2000)
speed = 100;
else
speed = 10;
if (PHYConfig & 0x0100)
duplex = 'F';
else
duplex = 'H';
*/
switch (OUI)
{
case PHY_OUI_NATIONAL:
PHYConfig = PHYAccess(PHYAdd, PHY_NATIONAL_PAR, OPRead, 0);
if (PHYConfig & PHY_NATIONAL_PAR_DUPLEX)
duplex = 'F';
else
duplex = 'H';
if (PHYConfig & PHY_NATIONAL_PAR_SPEED_10)
speed = 10;
else
speed = 100;
break;
case PHY_OUI_TDK:
PHYConfig = PHYAccess(PHYAdd, PHY_TDK_DIAG, OPRead, 0);
PHYConfig = PHYAccess(PHYAdd, PHY_TDK_DIAG, OPRead, 0);
if(
(
(Revision < 7) &&
((PHYConfig & 0x300) == 0x300)
)
||
(
(Revision >= 7) &&
(PHYConfig & PHY_TDK_DIAG_RATE)
)
)
speed = 100;
else
speed = 10;
if ((Revision >= 7) && (PHYConfig & PHY_TDK_DIAG_DUPLEX))
duplex = 'F';
else
duplex = 'H';
break;
case PHY_OUI_QSI:
PHYConfig = PHYAccess(PHYAdd, PHY_QSI_BASETX, OPRead, 0);
PHYConfig &= PHY_QSI_BASETX_OPMODE_MASK;
if(
(PHYConfig & PHY_QSI_BASETX_OPMODE_10FD) ||
(PHYConfig & PHY_QSI_BASETX_OPMODE_100FD)
)
duplex = 'F';
else
duplex = 'H';
if(
(PHYConfig & PHY_QSI_BASETX_OPMODE_100HD) ||
(PHYConfig & PHY_QSI_BASETX_OPMODE_100FD)
)
speed = 100;
else
speed = 10;
break;
case PHY_OUI_SEEQSMSC:
PHYConfig = PHYAccess(PHYAdd, PHY_SEEQ_STATUS_OUTPUT, OPRead, 0);
if (PHYConfig & PHY_SEEQ_DPLX_DET)
duplex = 'F';
else
duplex = 'H';
if (PHYConfig & PHY_SEEQ_SPD_DET)
speed = 100;
else
speed = 10;
break;
default:
PHYConfig = PHYAccess(PHYAdd, 0, OPRead, 0);
if (PHYConfig & 0x2000)
speed = 100;
else
speed = 10;
if (PHYConfig & 0x0100)
duplex = 'F';
else
duplex = 'H';
}
}
printf("Speed = %d Mbps ", speed);
printf("Duplex Mode = %c\n\r\n\r", duplex);
if (!quiet)
{
// Display the PHY register set
textcolor(CYAN);
highvideo();
cprintf("PHY Register Set Values after operation performed (if any):\n\r");
textcolor(WHITE);
printf("Offset Data ");
printf("Offset Data ");
printf("Offset Data ");
printf("Offset Data \n\r");
printf("-------------------------------------------------------------------------\n\r");
for (i=0;i<8;i++)
{
if(OUI == PHY_OUI_TDK) PHYAccess(PHYAdd,i,OPRead,0);
printf("%02Xh %04Xh ",i,PHYAccess(PHYAdd,i,OPRead,0));
if(OUI == PHY_OUI_TDK) PHYAccess(PHYAdd,i+8,OPRead,0);
printf("%02Xh %04Xh ",i+8,PHYAccess(PHYAdd,i+8,OPRead,0));
if(OUI == PHY_OUI_TDK) PHYAccess(PHYAdd,i+16,OPRead,0);
printf("%02Xh %04Xh ",i+16,PHYAccess(PHYAdd,i+16,OPRead,0));
if(OUI == PHY_OUI_TDK) PHYAccess(PHYAdd,i+24,OPRead,0);
printf("%02Xh %04Xh \n\r",i+24,PHYAccess(PHYAdd,i+24,OPRead,0));
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -