Hi,
I'm using AM335x MPU, i'm planing to use micrel KSZ9021RL gigabit PHY on AM335x.
is the ethernet device drive from AM335x EVM SDK is generic?
Thanks
Keldy
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Keldy
Ethernet driver is generic and doesn't depend on PHY. If the phy has no errata, then generic phy driver in the linux should work fine.
with regards
Mugunthan V N
Hi Mugunthan,
After I replace AR8031 phy with micrel KSZ9021RL phy,
in u-boot, when i enter "dhcp",
u-boot#dhcp
link up on port 1, speed 100, full duplex
BOOTP broadcast 1
BOOTP broadcast 2
BOOTP broadcast 3
BOOTP broadcast 4
.....until BOOTP broadcast 10 then repeat again
seen like the ethernet can't work properly and can't get IP address.
Why this will happen?
Do i need to change something in u-boot code, like the phy device id, phyaddr or others thing else?
Thanks & Regards
Keldy
Keldy
U-Boot Supports only EMAC 0 by default. From the logs it shows that Ethernet is connected to EMAC 1.
Did you ported U-Boot to support EMAC 1 from the Porting guide Wiki.
http://processors.wiki.ti.com/index.php/TI81xx_PSP_Porting_Guide#CPSW_EMAC_1_bringup_in_uboot
If you have two eEthernet pinned out, can you try connecting with EMAC0.
with regards
Mugunthan V N
Hi,
I'm using AM335x MPU, that have only one EMAC and two port, port 1 and port 2. The micrel KSZ9021RL phy was connected to the port 1.
Port 1 previously connected to Atheros AR8031 phy which is working properly, when i change to micrel KSZ9021RL phy, the ethernet not working anymore.
Any idea?
Thanks & Regards
Keldy
Keldy
Can you confirm the connection in the Schematics, Because in U-Boot port 1 is referenced to EMAC 1 and not EMAC 0.
Also check if RGMII internal delay is taken care.
with regards
Mugunthan V N
Hi Mugunthan,
here is my connection,
RGMII interface:
Am335x Pin | connect to | Micrel PHY KSZ9021RL |
GMII1_TXCLK | GTX_CLK | |
GMII1_TXD0 | TXD0 | |
GMII1_TXD1 | TXD1 | |
GMII1_TXD2 | TXD2 | |
GMII1_TXD3 | TXD3 | |
GMII1_TXEN | TXEN | |
GMII1_RXCLK | RX_CLK | |
GMII1_RXD0 | RXD0 | |
GMII1_RXD1 | RXD1 | |
GMII1_RXD2 | RXD2 | |
GMII1_RXD3 | RXD3 | |
GMII1_RXDV | RX_DV | |
GMII1_MDIO_CLK | MDC | |
GMII1_MDIO_DATA | MDIO |
For your info, I'm using AM335x EVM board and sdk.
How to check the internal delay?
Thanks & Regards
Keldy
Look at the gmii_sel register at 0x44e10650. Bits 1:0 select the mode for port1 (rgmii = 10) and bit 4 selects the internal delay. See the Control Module chapter of the TRM.
Steve K.
Keldy
In U-Boot EMAC 0 is attached to Port 0 in software, but it is showing Port 1is connected.
Can you check the phy address is populated in the devices structure properly. You can look for phy_id in the following location
board/ti/am335x/evm.c:struct cpsw_slave_data cpsw_slaves[] - phy_id
with regards
Mugunthan V N
Hi, after i change my phy addr to 0x00, now link up on port 0.
in u-boot, when i type "dhcp":
U-boot#dhcp
link up on port 0, speed 100, full duplex
BOOTP broadcast 1
BOOTP broadcast 2
......until BOOTP broadcast 10 and repeat again
seem like the micrel phy still not working properly. Any idea?
Thanks & Regards
Keldy
Keldy
Can you disable the RGMII internal delay by enabling the bits in gmii_sel
with regards
Mugunthan V N
As mentioned in your other E2E forum post titled “Ethernet PHY connection and configuration“, the KSZ9021 has different default timing for the RGMII signals.
You must configure the KSZ9021 to meet the timing requirements defined in the AM335x data sheet.
The receive data is transferred with respect to the receive clock and the transmit data is transferred with respect to the transmit clock. You need to insure all timing parameters of both devices are within the specified operating range. This may require timing adjustments via the KSZ9021RL RGMII Clock and Control Pad Skew and RGMII RX Data Pad Skew registers.
Note: The AM335x has the internal delay mode enabled by default and this is not supported so you must disable the internal delay mode in AM335x and adjust RGMII timing using the timing adjustment features in KSZ9021.
Regards,
Paul
Hi,
I had disable the internal delay by changing file in "ti-sdk-am335x-evm-05.03.00.00/board-support/u-boot-2011.09-psp04.06.00.02/board/ti/am335x/evm.c"
int board_init(void)
{
__raw_writel(0x00111010, gmii_sel); --------------------disable internal delay, enable RGMII
In adjustment of RGMII timing of KSZ9021 micrel phy, i have no idea how to do it. Any tutorial that i can refer ?
Thanks & Regards
Keldy
To change the phy timings you use the MDIO interface to modify phy registers. In u-boot, you would use the miiphy_read() and mmiphy_write() routines. In u-boot, look in evm.c for the evm_phy_init() routine. You can see where code reads registers MII_PHYSID1 and MII_PHYSID2 to determine which phy is used. You would want to add code to test for your phy and, if found, program the RGMII Clock and Control Pad Skew register (address 260) and the RTMII RX Data Pad Skew register (address 261). I found these addresses in the Micrel datasheet.
I asked Paul for more information about these registers and he said:
He needs to check the timing of each RGMII signal. This calculation is done by using the minimum setup/hold time input requirements, the min/max output characteristics, and PCB propagation delays of each signal to determine how to configure these registers.
For example, the RX data to RX clock output characteristics of the KSZ9021 is +/-500ps and the AM335x input requires a minimum 1ns setup and hold time to operate properly. If the PCB propagation time of RX data and RX clock are equal, the RX clock would need to be delayed in the KSZ9021 about 1.5ns - 2ns to center the clock edge in the valid data window.
Steve K.
Hi,
base on ksz9021 datasheet, the TskewT min/max is +/- 500ps, TskewR max is 2.6ns, AM335x setup/hold time min is 1ns, assume PCB propagation delay is same.
RXC skew delay about 1.5ns(500ps + 1ns) to 3.1ns(500ps + 2.6ns)
TXC skew delay about 1.5ns(500ps + 1ns) to 3.1ns(500ps + 2.6ns)
RXCTL, TXCTL, RXD[0-3] skew delay set to 0ns
ksz9021 phy, register 260:
default value | default delay | new value | new delay | |
RXC PAD Skew (0.2ns/step) | 0111 | 0.2 x 7 = 1.4ns | 1000 | 0.2 x 8 = 1.6ns |
RX_CTL PAD Skew (0.2ns/step) | 0111 | 0.2 x 7 = 1.4ns | 0000 | 0.2 x 0 = 0ns |
TXC PAD Skew (0.2ns/step) | 0111 | 0.2 x 7 = 1.4ns | 1000 | 0.2 x 8 = 1.6ns |
TX_CTL PAD Skew(0.2ns/step) | 0111 | 0.2 x 7 = 1.4ns | 0000 | 0.2 x 0 = 0ns |
register 261
default value | default delay | new value | new delay | |
RXD3 PAD Skew (0.2ns/step) | 0111 | 0.2 x 7 = 1.4ns | 0000 | 0.2 x 0 = 0ns |
RXD2 PAD Skew (0.2ns/step) | 0111 | 0.2 x 7 = 1.4ns | 0000 | 0.2 x 0 = 0ns |
RXD1 PAD Skew (0.2ns/step) | 0111 | 0.2 x 7 = 1.4ns | 0000 | 0.2 x 0 = 0ns |
RXD0 PAD Skew(0.2ns/step) | 0111 | 0.2 x 7 = 1.4ns | 0000 | 0.2 x 0 = 0ns |
Am i correct with the register new configuration?
Thanks & Regards
Keldy
Hello Keldy,
After reviewing the Micrel datasheet, I agree that you are moving in the right direction, but I would suggest trying to center the data a bit more by setting 0x104 [15:0] to 0x9797. This would set the new delay for TXC and RXC to 1.8ns while leaving RX_CTL and TX_CTL at their default values.
Keep in mind this number may still need to be adjusted higher or lower based on the specifics of your design, but this should be a good start.
Hi,
How about the RXD[0-3] skew delay ? leave it to default value 0x7777, or change to 0x0000 ?
The miiphy_read() and miiphy_write() function only allow 8 bits phy register address, writing value to phy register 0x104 and 0x105 using miiphy_write() make writing value to phy register 0x04 and 0x05.
Any other method to write to phy register 0x104 and 0x105?
Thanks & Regards
Keldy
Yes,
Please set the RXD[0-3] skew delays to '0'. Again, you may have to tune these values based on the specifics of your implementation.
As for extended register methods, please use the Extended Register Read and Extended Register Write functionality present in this PHY. This is described on page 33 of the KSZ9021 datasheet.
Keldy, please post back here if you have success getting the Micrel PHY to work with these settings. We are laying out a board with the same PHY and may have to go through the same process. Perhaps if we can get the Micrel chip timings right we can add support for this phy to the u-boot tree.
It looks like there shouldn't be anything changed in the kernel right? Just in u-boot?
Hi Keldy,
Any luck with the PHY? I have absolutely the same problem. I've stumbled upon this thread and am just curious if you get it work. I've tried everything including Extended Registers with no luck. And Micrel's tech support is just unresponsive, to say the least.
Thank you,
Vlad.
Hi,
it works! it was the skew delay problem. The ethernet driver is generic.
setting the micrel phy register (0x104) to value 0x9797, and register(0x105) to value 0x0000 make my ethernet working. But there is a failure sometime, need to tune the skew delay properly to make sure working properly.
Many Thanks to Paul, Steve K, and DK.
Thanks & Regards
Keldy
Hi Keldy,
You mentioned above that you were only making changes in U-boot, not Linux. In U-Boot, is it operating at 100Mbit/s or 1000Mbit/s? Did you get it to work in Linux?
Currently we have the same PHY operating at 100Mbit/s, and only in U-boot. Our skew delays are slightly different (more optimized for the required delay and our hardware setup), and we're setting them in both U-boot and Linux, but in U-boot it is limited to 100Mbit/s and in Linux it comes up and then goes down as soon as it is actually configured with the cpsw driver. Therefore, I'm curious if you actually got it to work in Linux.
Thanks,
Russell
Hi,
only make changes in u-boot, i use ' mii ' command to write data to phy register, operating speed is 100Mbit/s, and i can boot kernel image and file system through network, and i can telnet into my board from linux PC. For 1000Mbit/s i haven't test yet. At least know AM335x SDK driver can support micrel phy, what need to do is tuning the skew.
Thanks and Regards
Keldy
Hi,
We are using DM8148 on our board. We are using EMAC 1 as our Ethernet interface. AR8031 is our phy.
In the u-boot the board works fine for 100Mbps. when we try using different data rate of 1000Mbps the board autonegotiation happens and the speed is reduced to 100Mbps automatically. here is the log:
link up on port 0, speed 1000, full duplex
Using cpsw device
TFTP from server xx.xx.xx.xx; our IP address is xx.xx.xx.xx
Filename 'uImage'.
Load address: 0x81000000
Loading: link down on port 0
T link up on port 0, speed 100, full duplex
T ##############################
As you can see initially the link is up for 1000 but then it comes down and goes up to 100. We want it to work on 1000 Mbps.
Same problem is seen with 10Mbps also. Please help!!
Thanks
Prakash
Hello Keldy
can you please explain your suggested value of 0x9797?
i understand why skewing the clock by 1.8ns
but isn't the TX_CTL treated as data? and therefore should have same value as the data -> 0?
why not therefore use 0x9090?
Thanks
Oren.
Hi Keldy and all
I'm trying to use the KSZ9031 phy (linux), but it has not worked yet.
I tryed to set the RXC PAD Skew, TXC PAD Skew and RXDx PAD Skew, but it fails allways.
My code is like:
#define MMD_ACCESS_CTRL 0xd
#define MMD_ACCESS_REG_DATA 0xe
#define MMD_ACCESS_REG_MODE 0x0000
#define MMD_ACCESS_DATANOPOST_MODE 0x4000
#define MMD_ACCESS_DATAPOST_MODE 0x8000
#define MMD_ACCESS_DATAPOSTWRTONLY_MODE 0xc000
#define KSZ9031_PHY_CLK_PAD_SKEW_REG 0x08
#define KSZ9031_RGMII_CLK_DLY 0x2d6
#define KSZ9031_PHY_RXD_PAD_SKEW_REG 0x05
#define KSZ9031_RGMII_RXD_DLY 0x0000
static int wise_dly_phy_fixup(struct phy_device *phydev)
{
int temp;
/// CLK
phy_write(phydev, MMD_ACCESS_CTRL,MMD_ACCESS_REG_MODE|0x02);
phy_write(phydev, MMD_ACCESS_REG_DATA, KSZ9031_PHY_CLK_PAD_SKEW_REG);
phy_write(phydev, MMD_ACCESS_CTRL,MMD_ACCESS_DATANOPOST_MODE|0x02);
temp = phy_read(phydev, MMD_ACCESS_REG_DATA);
pr_info("phy read clk = 0x%x\n",temp);
phy_write(phydev, MMD_ACCESS_REG_DATA, (temp&0xFC00) | KSZ9031_RGMII_CLK_DLY);
temp = phy_read(phydev, MMD_ACCESS_REG_DATA);
pr_info("phy read clk = 0x%x\n",temp);
/// RXData
phy_write(phydev, MMD_ACCESS_CTRL,MMD_ACCESS_REG_MODE|0x02);
phy_write(phydev, MMD_ACCESS_REG_DATA, KSZ9031_PHY_RXD_PAD_SKEW_REG);
phy_write(phydev, MMD_ACCESS_CTRL,MMD_ACCESS_DATANOPOST_MODE|0x02);
temp = phy_read(phydev, MMD_ACCESS_REG_DATA);
pr_info("phy read rxd = 0x%x\n",temp);
phy_write(phydev, MMD_ACCESS_REG_DATA, KSZ9031_RGMII_RXD_DLY);
temp = phy_read(phydev, MMD_ACCESS_REG_DATA);
pr_info("phy read rxd = 0x%x\n",temp);
return 0;
}
/**
* Custom board
*/
static void setup_customboard(void)
{
am335x_mmc[0].gpio_wp = -EINVAL;
_configure_device(...
am33xx_cpsw_init(AM33XX_CPSW_MODE_RGMII, NULL, NULL);
// Micrel ksz9031 Clk delay Phy fixup
phy_register_fixup_for_uid(PHY_ID_KSZ9031, MICREL_PHY_ID_MASK,
wise_dly_phy_fixup);
}
When I try configuring network, the kernel outputs
Configuring network interfaces... [ 5.478391] phy read clk = 0x3ed6
[ 5.482085] phy read clk = 0x3ed6
[ 5.486050] phy read rxd = 0x0
[ 5.489495] phy read rxd = 0x0
[ 5.492692] net eth0: CPSW phy found : id is : 0x221621
eth0 no wireless extensions.
udhcpc (v1.20.2) started
Sending discover...
[ 8.488169] PHY: 0:00 - Link is Up - 100/Full
Sending discover...
Sending discover...
No lease, failing
done.
I'm using the second eth port.
Any help is wellcome.
Thank's!
Problem was resolved!
I had seen this following message:
[ 1.202098] davinci_mdio.0: probed
[ 1.205702] davinci_mdio davinci_mdio.0: phy[0]: device 0:00, driver Micrel KSZ9031 Gigabit PHY, id 0x221621
[ 1.215465] davinci_mdio davinci_mdio.0: phy[3]: device 0:03, driver Micrel KSZ9031 Gigabit PHY, id 0x221621
But when I connected cable, I saw something like
[ 8.488169] PHY: 0:00 - Link is Up - 100/Full
As I was using the second eth port (there was nothing on first eth), I changed this
am33xx_cpsw_init(AM33XX_CPSW_MODE_RGMII, NULL, NULL);
to
am33xx_cpsw_init(AM33XX_CPSW_MODE_RGMII, "0:00", "0:03");
The gigabit eth is working fine now. Even if I don't make delay adjust.
Regards,
Andre
What kernel rev are you on?
I am building up a Beaglebone AM335X based design and switched to a Micrel KSZ9031 Ethernet PHY and it does not work. The current driver for the KSZ9031 (micrel.c) seems to be the latest however I have found documentation from Micrel that it only works with the 3.8 kernel (our kernel is 3.2) and I only have one parameter to am33xx_cpsw_init so I cannot make delay adjustments. Do you know at which point in the kernel distribution am33xx_cpsw_init was upgraded to allow the delay changes?
-BL
Hi, Bruce
I'm using 3.2 kernel, from ti-sdk-am335x-evm-05.07.00.
Yes, micrel driver is for 3.8 kernel, but I've adjusted it for 3.2 one:
/* * drivers/net/phy/micrel.c * * Driver for Micrel PHYs * * Author: David J. Choi * * Copyright (c) 2010 Micrel, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * Support : Micrel Phys/switches: * Giga phys: ksz9021, ksz9031 * 100/10 Phys: ksz8001, ksz8021, ksz8031, ksz8041, ksz8051, * ksz8061, ksz8081, ksz8091, * ksz8721, ksz8737, * Switches: ksz8873 */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/phy.h> #include <linux/micrel_phy.h> /* Operation Mode Strap Override */ #define MII_KSZPHY_OMSO 0x16 #define KSZPHY_OMSO_B_CAST_OFF (1 << 9) #define KSZPHY_OMSO_RMII_OVERRIDE (1 << 1) #define KSZPHY_OMSO_MII_OVERRIDE (1 << 0) /* general Interrupt control/status reg in vendor specific block. */ #define MII_KSZPHY_INTCS 0x1B #define KSZPHY_INTCS_JABBER (1 << 15) #define KSZPHY_INTCS_RECEIVE_ERR (1 << 14) #define KSZPHY_INTCS_PAGE_RECEIVE (1 << 13) #define KSZPHY_INTCS_PARELLEL (1 << 12) #define KSZPHY_INTCS_LINK_PARTNER_ACK (1 << 11) #define KSZPHY_INTCS_LINK_DOWN (1 << 10) #define KSZPHY_INTCS_REMOTE_FAULT (1 << 9) #define KSZPHY_INTCS_LINK_UP (1 << 8) #define KSZPHY_INTCS_ALL (KSZPHY_INTCS_LINK_UP |\ KSZPHY_INTCS_LINK_DOWN) /* general PHY control reg in vendor specific block. */ #define MII_KSZPHY_CTRL 0x1F /* bitmap of PHY register to set interrupt mode */ #define KSZPHY_CTRL_INT_ACTIVE_HIGH (1 << 9) #define KSZ90X1_CTRL_INT_ACTIVE_HIGH (1 << 14) #define KSZ8737_CTRL_INT_ACTIVE_HIGH (1 << 14) #define KSZ8051_RMII_50MHZ_CLK (1 << 7) static int kszphy_ack_interrupt(struct phy_device *phydev) { /* bit[7..0] int status, which is a read and clear register. */ int rc; rc = phy_read(phydev, MII_KSZPHY_INTCS); return (rc < 0) ? rc : 0; } static int kszphy_set_interrupt(struct phy_device *phydev) { int temp; temp = (PHY_INTERRUPT_ENABLED == phydev->interrupts) ? KSZPHY_INTCS_ALL : 0; return phy_write(phydev, MII_KSZPHY_INTCS, temp); } static int kszphy_config_intr(struct phy_device *phydev) { int temp, rc; /* set the interrupt pin active low */ temp = phy_read(phydev, MII_KSZPHY_CTRL); temp &= ~KSZPHY_CTRL_INT_ACTIVE_HIGH; phy_write(phydev, MII_KSZPHY_CTRL, temp); rc = kszphy_set_interrupt(phydev); return rc < 0 ? rc : 0; } static int ksz90x1_config_intr(struct phy_device *phydev) { int temp, rc; /* set the interrupt pin active low */ temp = phy_read(phydev, MII_KSZPHY_CTRL); temp &= ~KSZ90X1_CTRL_INT_ACTIVE_HIGH; phy_write(phydev, MII_KSZPHY_CTRL, temp); rc = kszphy_set_interrupt(phydev); return rc < 0 ? rc : 0; } static int ksz8737_config_intr(struct phy_device *phydev) { int temp, rc; /* set the interrupt pin active low */ temp = phy_read(phydev, MII_KSZPHY_CTRL); temp &= ~KSZ8737_CTRL_INT_ACTIVE_HIGH; phy_write(phydev, MII_KSZPHY_CTRL, temp); rc = kszphy_set_interrupt(phydev); return rc < 0 ? rc : 0; } static int kszphy_config_init(struct phy_device *phydev) { return 0; } static int ksz8021_config_init(struct phy_device *phydev) { const u16 val = KSZPHY_OMSO_B_CAST_OFF | KSZPHY_OMSO_RMII_OVERRIDE; phy_write(phydev, MII_KSZPHY_OMSO, val); return 0; } static int ks8051_config_init(struct phy_device *phydev) { int regval; if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) { regval = phy_read(phydev, MII_KSZPHY_CTRL); regval |= KSZ8051_RMII_50MHZ_CLK; phy_write(phydev, MII_KSZPHY_CTRL, regval); } return 0; } #define KSZ8873MLL_GLOBAL_CONTROL_4 0x06 #define KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX (1 << 6) #define KSZ8873MLL_GLOBAL_CONTROL_4_SPEED (1 << 4) int ksz8873mll_read_status(struct phy_device *phydev) { int regval; /* dummy read */ regval = phy_read(phydev, KSZ8873MLL_GLOBAL_CONTROL_4); regval = phy_read(phydev, KSZ8873MLL_GLOBAL_CONTROL_4); if (regval & KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX) phydev->duplex = DUPLEX_HALF; else phydev->duplex = DUPLEX_FULL; if (regval & KSZ8873MLL_GLOBAL_CONTROL_4_SPEED) phydev->speed = SPEED_10; else phydev->speed = SPEED_100; phydev->link = 1; phydev->pause = phydev->asym_pause = 0; return 0; } static int ksz8873mll_config_aneg(struct phy_device *phydev) { return 0; } static struct phy_driver ksphy_driver[] = { { .phy_id = PHY_ID_KSZ8737, .phy_id_mask = 0x00fffff0, .name = "Micrel KSZ8737", .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = ksz8737_config_intr, .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_KSZ8021, .phy_id_mask = 0x00ffffff, .name = "Micrel KSZ8021 or KSZ8031", .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .config_init = ksz8021_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = kszphy_config_intr, .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_KSZ8041, .phy_id_mask = 0x00fffff0, .name = "Micrel KSZ8041", .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = kszphy_config_intr, .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_KSZ8051, .phy_id_mask = 0x00fffff0, .name = "Micrel KSZ8051", .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .config_init = ks8051_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = kszphy_config_intr, .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_KSZ8001, .name = "Micrel KSZ8001 or KSZ8721", .phy_id_mask = 0x00ffffff, .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = kszphy_config_intr, .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_KSZ8081, .name = "Micrel KSZ8081 or KSZ8091", .phy_id_mask = 0x00fffff0, .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = kszphy_config_intr, .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_KSZ8061, .name = "Micrel KSZ8061", .phy_id_mask = 0x00fffff0, .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = kszphy_config_intr, .driver = { .owner = THIS_MODULE,}, }, { .phy_id = PHY_ID_KSZ9021, .phy_id_mask = 0x00fffffe, .name = "Micrel KSZ9021 Gigabit PHY", .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = ksz90x1_config_intr, .driver = { .owner = THIS_MODULE, }, }, { .phy_id = PHY_ID_KSZ9031, .phy_id_mask = 0x00fffff0, .name = "Micrel KSZ9031 Gigabit PHY", .features = (PHY_GBIT_FEATURES /*| SUPPORTED_Pause | SUPPORTED_Asym_Pause*/), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = ksz90x1_config_intr, .driver = { .owner = THIS_MODULE, }, }, { .phy_id = PHY_ID_KSZ8873MLL, .phy_id_mask = 0x00fffff0, .name = "Micrel KSZ8873MLL Switch", .features = (SUPPORTED_Pause | SUPPORTED_Asym_Pause), .flags = PHY_HAS_MAGICANEG, .config_init = kszphy_config_init, .config_aneg = ksz8873mll_config_aneg, .read_status = ksz8873mll_read_status, .driver = { .owner = THIS_MODULE, }, } }; static int __init ksphy_init(void) { int ret; char c = 8; // for(c=0;c<10;c++){ ret = phy_driver_register(&ksphy_driver[c]); if (ret) goto err; // } return 0; err: phy_driver_unregister(&ksphy_driver[c]); return ret; } static void __exit ksphy_exit(void) { char c; for(c=0;c<10;c++){ phy_driver_unregister(&ksphy_driver[c]); } } module_init(ksphy_init); module_exit(ksphy_exit); MODULE_DESCRIPTION("Micrel PHY driver"); MODULE_AUTHOR("David J. Choi"); MODULE_LICENSE("GPL"); static struct mdio_device_id __maybe_unused micrel_tbl[] = { { PHY_ID_KSZ9021, 0x00fffffe }, { PHY_ID_KSZ9031, 0x00fffff0 }, { PHY_ID_KSZ8001, 0x00ffffff }, { PHY_ID_KSZ8737, 0x00fffff0 }, { PHY_ID_KSZ8021, 0x00ffffff }, { PHY_ID_KSZ8041, 0x00fffff0 }, { PHY_ID_KSZ8051, 0x00fffff0 }, { PHY_ID_KSZ8061, 0x00fffff0 }, { PHY_ID_KSZ8081, 0x00fffff0 }, { PHY_ID_KSZ8873MLL, 0x00fffff0 }, { } }; MODULE_DEVICE_TABLE(mdio, micrel_tbl);
I hope it helps.
Regards,
Andre
Hey Andre,
Thanks for the quick response. I will give it a try.
Can you post kernel/arch/arm/mach-omap2/devices.c as well? Any other related files that were in the fix would be much appreciated.
-BL
I did not modify that file, just board-am335xevm.c, but all software modifications were already posted above, except micrel_phy.h (trivial).
Regards,
André
Ok, I see that I don't have the patch that updates am33xx_cpsw_init() to obtain mac mode & phy id. My am33xx_cpsw_init() only takes one param. This is strange because I see that I am on 3.2.42 and the patches are being installed but that patch does not appear to be in there.
Maybe there is a later release I should pull? I don't want to go too late where they get away from the board files and move to device trees as we have mods in our board file currently.
-BL
I suggest you get TI software: http://downloads.ti.com/sitara_linux/esd/AM335xSDK/latest/index_FDS.html
Regards
Yes I will look into that next, so far its not working. I have the phy_fixup routine in there to ajust RXD delay and CLK delay and the driver you posted and this is what I see;
from boot....
...
[ 1.140869] davinci_mdio davinci_mdio.0: davinci mdio revision 1.6
[ 1.147399] davinci_mdio davinci_mdio.0: detected phy mask fffffffe
[ 1.155334] phy read clk = 0x3def
[ 1.159027] phy read clk = 0x3e00
[ 1.163055] phy read rxd = 0x7777
[ 1.166748] phy read rxd = 0x20
[ 1.170196] davinci_mdio.0: probed
[ 1.173828] davinci_mdio davinci_mdio.0: phy[0]: device 0:00, driver Micrel KSZ9031 Gigabit PHY
...
then after that finishes...
Started Login Service [ OK ]
[ 4.174224] ip_tables: (C) 2000-2006 Netfilter Core Team
[ 4.672424] phy read clk = 0x3e00
[ 4.676177] phy read clk = 0x3e00
[ 4.680145] phy read rxd = 0x20
[ 4.683715] phy read rxd = 0x20
[ 4.687042]
[ 4.687042] CPSW phy found : id is : 0x221622
[ 4.693939] PHY 0:01 not found
[ 4.699615] ADDRCONF(NETDEV_UP): eth0: link is not ready
Starting Serial Getty on ttyO0...
Started Serial Getty on ttyO0 [ OK ]
.---O---.
| | .-. o o
| | |-----.-----.-----.| | .----..-----.-----.
| | | __ | ---'| '--.| .-'| | |
| | | | | |--- || --'| | | ' | | | |
'---'---'--'--'--. |-----''----''--' '-----'-'-'-'
-' |
'---'
The Angstrom Distribution beaglebone ttyO0
Angstrom v2012.05 - Kernel 3.2.42
beaglebone login: root (automatic login)
Last login: Sat Jan 1 00:00:04 UTC 2000 on ttyO0
root@beaglebone:~# ifconfig
eth0 Link encap:Ethernet HWaddr BC:6A:29:A0:DE:29
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
then about 30s later...
root@beaglebone:~# [ 34.682495] PHY: 0:00 - Link is Up - 10/Full
[ 34.687255] ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
then after a minute or so it appears to fail to get a DHCP address and assignes an IP from the homeless network (169.254.0.0)
root@beaglebone:~# ifconfig
eth0 Link encap:Ethernet HWaddr BC:6A:29:A0:DE:29
inet addr:169.254.26.102 Bcast:169.254.255.255 Mask:255.255.0.0
inet6 addr: fe80::be6a:29ff:fea0:de29/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:39 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:11137 (10.8 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Interestingly, Tx seems to work but Rx is not. I've tried several RXD delay and CLK delay combos to no avail. This is the same response I got with 3.2.42 out of the box so I don't think the orig driver was the problem.
Any ideas?
-BL
Hi
We are also facing same issue with KSZ9021 micrel PHY, intially it did not worked with 10/100/1000 any speed but after adjusting delays(F0F0 ,0000,0000) it works for 10/100 speeds but still we are facing issue with 1000Mbps.
looks me F0F0(104 reg)0000(105reg)0000(106reg) delays values are correct as all my TX pairs and RX pairs are length macthed, by setting above values we are ensure that min set up time of 1.3ns in any case(-500 skew case also)
Can you please any one suggest me whats going wrong with 1000Mbps?
Thanks
Shiva
As it turns out we did not have to modify signal timing. Our issue (after we got all our HW issues corrected) turned out to be pin muxing. Make sure your pin muxing is set correctly whether you are doing this in the source code or setting it after you boot.
-BL
Hi
Our case board is working fie with the 100Mbps,we are facing issue with 1000Mbps.looks like some timing issue in RGMII lines.
Thanks
Shiva
Keldy said:Hi,
It's work fine with gigabit ethernet.
Thanks & Regards
Keldy
Hi Keldy,
Your ethernet interface is working in gigabit mode with delays 0x9797 and 0x0000? With these delays, my ethernet interface work only in 100M mode.
Best regards,
Christiano Belli.
The fastest and easiest way to dial-in your timing is to instrument the RGMII interface with a scope and use the wave forms as a guide to tune the PHY as needed. Hopefully, you did a timing analysis of the interface prior to PCB fab and your timing is off to a degree that the PHY can accommodate.