micrel公司一款优秀的PHY芯片,关于芯片的介绍参考:
[Datasheet PHY] ksz8081数据手册解读
系统版本:Ubuntu18.04-64
编译器版本:gcc version 7.4.0 (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04.1)
uboot版本:2018.07 -linux4sam_6.0
板子型号:at91sama5d3x-xplained
MCU型号:sama5d36
与ksz9031很相似,公众部分可参考:
1、如何找到uboot官网开发板默认配置文件路径
2、如何进行公共信息配置
3、如何核对开发板硬件的参数
4、如何对uboot功能进行裁剪
5、设备树文件存放位置,及IO配置
6、网卡初始化流程,程序入口如何调用驱动文件接口;
[Linux 底层]U-boot ksz9031网络驱动调试
关注微信公众号,回复“ksz8081驱动”,免费下载ksz8081的驱动源代码。
硬件参考图如下:
1、设备树更改
phy-mode = “rmii”; PHY的接口方式为RMII 外部需要提供50MHZ时钟,或者通过内部倍频;
gpios,因为硬件设计上,把芯片的电源和RST单独控制,可给芯片复位,或者进行上下电操作;可在应用层进行调用;
macb1: ethernet@f802c000 {
phy-mode = "rmii";
#address-cells = <1>;
#size-cells = <0>;
pinctrl-0 = <&pinctrl_mcb1_rst >;
status = "okay";
gpios = <
&pioC 18 GPIO_ACTIVE_HIGH ///poweren
&pioC 31 GPIO_ACTIVE_HIGH ///rst
>;
ethernet-phy@1 {
reg = <0x1>;
};
};
2、驱动初始化函数入口
#ifdef CONFIG_PHY_MICREL_KSZ8XXX
phy_micrel_ksz8xxx_init();
#endif
int phy_micrel_ksz8xxx_init(void)
{
printf("phy_micrel_ksz8xxx_init KSZ8081_drivern");
phy_register(&KSZ804_driver);
phy_register(&KSZ8031_driver);
phy_register(&KSZ8051_driver);
phy_register(&KSZ8081_driver);
phy_register(&KS8721_driver);
phy_register(&ksz8895_driver);
phy_register(&ksz886x_driver);
return 0;
}
50MHz晶振
static struct phy_driver KSZ8081_driver = {
.name = "Micrel KSZ8081",
.uid = 0x221560,
.mask = 0xfffff0,
.features = PHY_BASIC_FEATURES,
.config = &ksz_8081_config, //配置函数进行了重构,因为外部使用50M晶振,官网使用25M晶振
.startup = &genphy_startup,
.shutdown = &genphy_shutdown,
};
static int ksz_8081_config(struct phy_device *phydev)
{
int ret;
int regval;
//50M晶振配置
regval = phy_read(phydev, MDIO_DEVAD_NONE,MII_KSZPHY_CTRL);
regval |= KSZ8051_RMII_50MHZ_CLK;
phy_write(phydev, MDIO_DEVAD_NONE,MII_KSZPHY_CTRL, regval);
printf(" ksz_8081_config MII_KSZPHY_CTRL(0x1f) =0x%xn",regval);
ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO);
if (ret < 0)
return ret;
ret |= KSZPHY_OMSO_B_CAST_OFF;
//ret &= ~KSZPHY_OMSO_B_CAST_OFF;
printf(" ksz_8081_config MII_KSZPHY_OMSO(0x16) =0x%xn",ret);
ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO,
ret);
if (ret < 0)
return ret;
return genphy_config(phydev);
}
int genphy_config(struct phy_device *phydev)
{
int val;
u32 features;
features = (SUPPORTED_TP | SUPPORTED_MII
| SUPPORTED_AUI | SUPPORTED_FIBRE |
SUPPORTED_BNC);
/* Do we support autonegotiation? */
val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
printf("genphy_config phyaddr=%d,MII_BMSR(%d)=0x%xn",phydev->addr,MII_BMSR,val);
if (val < 0)
return val;
if (val & BMSR_ANEGCAPABLE)
features |= SUPPORTED_Autoneg;
if (val & BMSR_100FULL)
features |= SUPPORTED_100baseT_Full;
if (val & BMSR_100HALF)
features |= SUPPORTED_100baseT_Half;
if (val & BMSR_10FULL)
features |= SUPPORTED_10baseT_Full;
if (val & BMSR_10HALF)
features |= SUPPORTED_10baseT_Half;
if (val & BMSR_ESTATEN) {
val = phy_read(phydev, MDIO_DEVAD_NONE, MII_ESTATUS);
printf("genphy_config phyaddr=%d,MII_ESTATUS(%d)=0x%xn",phydev->addr,MII_ESTATUS,val);
if (val < 0)
return val;
if (val & ESTATUS_1000_TFULL)
features |= SUPPORTED_1000baseT_Full;
if (val & ESTATUS_1000_THALF)
features |= SUPPORTED_1000baseT_Half;
if (val & ESTATUS_1000_XFULL)
features |= SUPPORTED_1000baseX_Full;
if (val & ESTATUS_1000_XHALF)
features |= SUPPORTED_1000baseX_Half;
}
phydev->supported &= features;
phydev->advertising &= features;
genphy_config_aneg(phydev);
return 0;
}
/**
* genphy_config_aneg - restart auto-negotiation or write BMCR
* @phydev: target phy_device struct
*
* Description: If auto-negotiation is enabled, we configure the
* advertising, and then restart auto-negotiation. If it is not
* enabled, then we write the BMCR.
*/
int genphy_config_aneg(struct phy_device *phydev)
{
int result;
int ival = 0;
if (phydev->autoneg != AUTONEG_ENABLE)
return genphy_setup_forced(phydev);
#if 0
//set loopback
//Reg 0
ival |= (1 << 14 );
ival |= (1 << 6 );
ival &= ~(1 << 13 );
ival &= ~(1 << 12 );
ival |= (1 << 8 );
phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_ANENABLE & (~(1<<6)));
#endif
printf("genphy_config_aneg ival = 0x%x,test1111.n",ival);
result = genphy_config_advert(phydev);
if (result < 0) /* error */
{
return result;
}
printf("genphy_config_aneg result=%d test2222.n",result);
if (result == 0) {
/*
* Advertisment hasn't changed, but maybe aneg was never on to
* begin with? Or maybe phy was isolated?
*/
int ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
printf("genphy_config_aneg MII_BMCR, ctl=0x%xn",ctl);
if (ctl < 0)
return ctl;
if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE))
result = 1; /* do restart aneg */
}
/*
* Only restart aneg if we are advertising something different
* than we were before.
*/
if (result > 0)
{
printf("genphy_config_aneg test3333.n");
result = genphy_restart_aneg(phydev);
}
return result;
}
3、编译之后,把u-boot.bin文件下载到板子,运行打印信息如下:
U-Boot 2018.07-linux4sam_6.0 (Oct 11 2020 - 23:57:20 -0700)
CPU: SAMA5D36
Crystal frequency: 12 MHz
CPU clock : 528 MHz
Master clock : 132 MHz
DRAM: 256 MiB
NAND: 256 MiB
MMC: Atmel mci: 0, Atmel mci: 1
Loading Environment from NAND... OK
In: serial@ffffee00
Out: serial@ffffee00
Err: serial@ffffee00
Netjack: macb_eth_probe phy-mode=mii,devname=ethernet@f0028000
eth0: ethernet@f0028000 [PRIME]macb_eth_probe phy-mode=rmii,devname=ethernet@f802c000
, eth1: ethernet@f802c000
Hit any key to stop autoboot: 0
=> pri
打印出phy-mode=rmii是从设备树里面读取的信息;
使用ping命令进行验证,是否能够正常通讯;
=> ping 192.168.2.108
CONFIG_DM_ETH _macb_init MACB_BIT(RMII) | MACB_BIT(CLKEN)
ethernet@f802c000: PHY present at 1,phy_id=0x22,macb->phy_addr=1
macb_phy_init name=ethernet@f802c000,phy_addr=1,ret=0
ksz_8081_config MII_KSZPHY_CTRL(0x1f) =0x8180
ksz_8081_config MII_KSZPHY_OMSO(0x16) =0x202
ethernet@f802c000: Starting autonegotiation...
ethernet@f802c000: Autonegotiation complete
ethernet@f802c000: link up, 100Mbps full-duplex (lpa: 0xcde1)
macb_phy_init udelay(3000)
Using ethernet@f802c000 device
gmacb send
ff ff ff ff ff ff aa ab c1 d2 e6 c6 08 06 00 01 08 00 06 04 00 01 aa ab c1 d2 e6 c6 c0 a8 01 64 00 00 00 00 00 00 c0 a8 02 6c
_macb_recv paddr=0x2fb6bec0, length=64,phy_addr=1
_macb_recv paddr=0x2fb6bf40, length=64,phy_addr=1
_macb_recv paddr=0x2fb6bfc0, length=64,phy_addr=1
_macb_recv paddr=0x2fb6c040, length=64,phy_addr=1
_macb_recv paddr=0x2fb6c0c0, length=64,phy_addr=1
_macb_recv paddr=0x2fb6c140, length=64,phy_addr=1
_macb_recv paddr=0x2fb6c1c0, length=114,phy_addr=1
_macb_recv paddr=0x2fb6c240, length=64,phy_addr=1
_macb_recv paddr=0x2fb6c2c0, length=64,phy_addr=1
上一篇:[linux 底层]u-boot EMMC驱动
下一篇:[Linux 底层]U-boot ksz9031网络驱动调试
推荐阅读最新更新时间:2024-10-30 11:19
设计资源 培训 开发板 精华推荐
- LTC3529 的典型应用 - 采用 2mm 3mm DFN 封装的 1.5A、1.5MHz 升压型 DC/DC 转换器
- TEA1999DB1546: TEA1999TS USB BC1.2反激同步整流控制器
- 电热手套2.0
- EP1020xS,QorIQ PowerPC 板是一款紧凑、经济高效且功能强大的平台,用于开发高性能网络控制设备
- 河北枣强中学nfc卡片
- 烧录夹子-pcb
- MC33074DTBR2G高速低压比较器典型应用
- OP284EPZ 高端负载电流监控器的典型应用
- LTC3427 的典型应用 - 采用 2mm x 2mm DFN 封装的 500mA、1.25MHz 同步升压型 DC/DC 转换器
- LT6656BCS6-5 的典型应用,用于基本连接的 5V 电压基准