📄 ks8721.c
字号:
/*
* File: ks8721.c
* Purpose: Driver for the Micrel KS8721 10/100 Ethernet PHY
*
* Notes:
*/
#include "m5275evb.h"
#include "mii.h"
#include "ks8721.h"
/********************************************************************/
/* Initialize the KS8721 PHY
*
* This function sets up the Auto-Negotiate Advertisement register
* within the PHY and then forces the PHY to auto-negotiate for
* it's settings.
*
* Params:
* fec_ch FEC channel
* phy_addr Address of the PHY.
* speed Desired speed (10BaseT or 100BaseTX)
* duplex Desired duplex (Full or Half)
*
* Return Value:
* 0 if MII commands fail
* 1 otherwise
*/
#define DEBUG
int
ks8721_init(uint8 fec_ch, uint8 phy_addr, uint8 speed, uint8 duplex)
{
int timeout;
uint16 settings;
/* Disable Auto-Negotiation */
if (!mii_write(fec_ch, phy_addr, KS8721_CTRL, 0))
return 0;
/* Reset the PHY */
if (!mii_write(fec_ch, phy_addr, KS8721_CTRL, KS8721_CTRL_RESET))
return 0;
/*
* Read back the contents of the CTRL register and verify
* that RESET is not set - this is a sanity check to ensure
* that we are talking to the PHY correctly. RESET should
* always be cleared.
*/
if (!mii_read(fec_ch, phy_addr, KS8721_CTRL, &settings))
return 0;
if (settings & KS8721_CTRL_RESET)
return 0;
if (speed == MII_10BASE_T)
{
settings = (uint16)((duplex == MII_FULL_DUPLEX)
? (KS8721_AN_ADV_10BT_FDX | KS8721_AN_ADV_10BT)
: KS8721_AN_ADV_10BT);
}
else /* (speed == FEC_MII_100BASE_TX) */
{
settings = (uint16)((duplex == MII_FULL_DUPLEX)
? (KS8721_AN_ADV_100BTX_FDX | KS8721_AN_ADV_100BTX
| KS8721_AN_ADV_10BT_FDX | KS8721_AN_ADV_10BT)
: (KS8721_AN_ADV_100BTX | KS8721_AN_ADV_10BT));
}
/* Set the Auto-Negotiation Advertisement Register */
if (!mii_write(fec_ch, phy_addr, KS8721_AN_ADV, settings))
return 0;
/* Enable Auto-Negotiation */
if (!mii_write(fec_ch, phy_addr, KS8721_CTRL, (KS8721_CTRL_ANE
| KS8721_CTRL_RESTART_AN)))
return 0;
for (timeout = 0; timeout < MII_TIMEOUT; ++timeout)
{
/* Read PHY status register */
if (!mii_read(fec_ch, phy_addr, KS8721_STAT, &settings))
return 0;
if (settings & KS8721_STAT_AN_COMPLETE)
break;
}
if (timeout == MII_TIMEOUT)
return 0;
/*
* Read 100BaseTX PHY Control Register
*/
if (!mii_read(fec_ch, phy_addr, KS8721_100TX_CTRL, &settings))
return 0;
/*
* Set the proper duplex in the FEC now that we have auto-negotiated
*/
if (((settings & KS8721_100TX_CTRL_MODE_MASK) == KS8721_100TX_CTRL_MODE_10HDX) ||
((settings & KS8721_100TX_CTRL_MODE_MASK) == KS8721_100TX_CTRL_MODE_100HDX))
fec_duplex(fec_ch, MII_HALF_DUPLEX);
else
fec_duplex(fec_ch, MII_FULL_DUPLEX);
#ifdef DEBUG
printf("\nPHY Mode: ");
switch (settings & KS8721_100TX_CTRL_MODE_MASK)
{
case KS8721_100TX_CTRL_MODE_AN :
printf("Auto-negotiating\n");
break;
case KS8721_100TX_CTRL_MODE_10HDX :
printf("10Mbps Half-duplex\n");
break;
case KS8721_100TX_CTRL_MODE_100HDX :
printf("100Mbps Half-duplex\n");
break;
case KS8721_100TX_CTRL_MODE_DEFAULT :
printf("Default\n");
break;
case KS8721_100TX_CTRL_MODE_10FDX :
printf("10Mbps Full-duplex\n");
break;
case KS8721_100TX_CTRL_MODE_100FDX :
printf("100Mbps Full-duplex\n");
break;
case KS8721_100TX_CTRL_MODE_ISOLATE :
printf("Isolation\n");
break;
default:
printf("Unknown\n");
}
#endif
return 1;
}
/********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -