Micrel is an excellent PHY chip. For more information about the chip, please refer to:
[Datasheet PHY] ksz8081 datasheet interpretation
System version: Ubuntu18.04-64
Compiler version: gcc version 7.4.0 (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04.1)
uboot version: 2018.07-linux4sam_6.0
Board model: at91sama5d3x-xplained
MCU model: sama5d36
Very similar to ksz9031, the public part can be referenced:
1. How to find the default configuration file path of the uboot official website development board
2. How to configure public information
3. How to check the parameters of the development board hardware
4. How to tailor the uboot function
5. Device tree file storage location and IO configuration
6. Network card initialization process, how to call the driver file interface at the program entry;
[Linux bottom layer] U-boot ksz9031 network driver debugging
Follow the WeChat public account and reply "ksz8081 driver" to download the driver source code of ksz8081 for free.
The hardware reference diagram is as follows:
1. Device tree changes
phy-mode = "rmii"; The interface mode of PHY is RMII. A 50MHZ clock needs to be provided externally, or through internal frequency multiplication;
gpios, because of the hardware design, the power supply and RST of the chip are controlled separately, which can reset the chip or perform power-on and power-off operations; it can be called at the application layer;
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. Driver initialization function entry
#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 crystal
static struct phy_driver KSZ8081_driver = {
.name = "Micrel KSZ8081",
.uid = 0x221560,
.mask = 0xfffff0,
.features = PHY_BASIC_FEATURES,
.config = &ksz_8081_config, //The configuration function has been reconstructed because the external crystal oscillator uses a 50M crystal oscillator and the official website uses a 25M crystal oscillator
.startup = &genphy_startup,
.shutdown = &genphy_shutdown,
};
static int ksz_8081_config(struct phy_device *phydev)
{
int ret;
int regval;
//50M crystal oscillator configuration
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 right;
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,
right);
if (ret < 0)
return right;
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. After compiling, download the u-boot.bin file to the board and run it to print the following information:
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
=> at
Printing out phy-mode=rmii is information read from the device tree;
Use the ping command to verify whether communication is normal;
=> 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
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=0x2fb6c340, length=96,phy_addr=1
_macb_recv paddr=0x2fb6c3c0, length=64,phy_addr=1
_macb_recv paddr=0x2fb6c4c0, length=64,phy_addr=1
_macb_recv paddr=0x2fb6c5c0, length=64,phy_addr=1
_macb_recv paddr=0x2fb6c640, length=96,phy_addr=1
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=0x2fb6c740, length=96,phy_addr=1
_macb_recv paddr=0x2fb6c7c0, length=96,phy_addr=1
_macb_recv paddr=0x2fb6c840, length=96,phy_addr=1
_macb_recv paddr=0x2fb6c8c0, length=96,phy_addr=1
_macb_recv paddr=0x2fb6c940, length=96,phy_addr=1
_macb_recv paddr=0x2fb6c9c0, length=96,phy_addr=1
_macb_recv paddr=0x2fb6cac0, length=64,phy_addr=1
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=0x2fb6cb40, length=96,phy_addr=1
_macb_recv paddr=0x2fb6cbc0, length=96,phy_addr=1
_macb_recv paddr=0x2fb6cc40, length=96,phy_addr=1
_macb_recv paddr=0x2fb6ccc0, length=64,phy_addr=1
_macb_recv paddr=0x2fb6cd41, length=64,phy_addr=1
_macb_recv paddr=0x2fb6cdc3, length=64,phy_addr=1
_macb_recv paddr=0x2fb6be41, length=64,phy_addr=1
_macb_recv paddr=0x2fb6bec0, length=64,phy_addr=1
Previous article:[Linux bottom layer] u-boot EMMC driver
Next article:[Linux bottom layer] U-boot ksz9031 network driver debugging
Recommended ReadingLatest update time:2024-11-23 06:52
- Popular Resources
- Popular amplifiers
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- Single-ended input and double-ended output circuit
- When calculating the circuit branch current and component voltage, how to determine whether the selected loop group is an independent loop using the loop current method?
- Evaluation summary: Domestic FPGA Gaoyun GW1N series development board
- What is IoT technology?
- The Analog Engineer's Circuit Design Cookbook: Amplifiers
- TGF4042 Function Signal Generator Review: Unboxing and Trial
- Wireless Alliance names Wi-Fi 6E for 802.11ax networks using 6GHz spectrum
- Exposing unscrupulous merchants [Jimu Microelectronics Flagship Store]
- esp32,stm32: add machine.I2S to support I2S protocol
- Two AT24C02 read and write examples on the I2C bus