We need to control Ethernet led on TX2, due to our product’s requirement.
Is there a way to manage the Etherent led on/off on TX2 as we expect?
Thank you,
We need to control Ethernet led on TX2, due to our product’s requirement.
Is there a way to manage the Etherent led on/off on TX2 as we expect?
Thank you,
Hi HuiW,
You need the Ethernet phy datasheet from Broadcom to know how to configure the register.
There is a patch for configuring LED behvaior.
Please refer to
and some stories in
https://devtalk.nvidia.com/default/topic/1025850/jetson-tx2/tx2-gbe-led-operation/
Now The LED state is below
1000M : right link led : yallow
left speed led : Orange ,but flashing
100M : right link led : OFF
left speed led : green, but flashing
Could you share what pins are green/orange/yellow LED connected to?
Previous patch would have some problems.
Please try this patch.
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index bc4577f..190741c 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -323,6 +323,21 @@ static int bcm54xx_config_init(struct phy_device *phydev)
reg |= BIT(14); /* Enable rx of extended pkts */
bcm89xx_shadow_write(phydev, MII_BCM89XX_SHD_AUX_CONTROL, reg);
}
+ /* Disable LOM-LED */
+ reg = bcm_phy_read_shadow(phydev, BCM54XX_SHD_RGMII_MODE);
+ reg = reg & ~(1 << 2);
+ reg = reg & ~(1 << 5);
+ reg = reg & ~(3);
+ bcm_phy_write_shadow(phydev, BCM54XX_SHD_RGMII_MODE, reg);
+
+ reg = bcm_phy_read_shadow(phydev, BCM89610_SHD_LEDS1);
+ bcm_phy_write_shadow(phydev, BCM89610_SHD_LEDS1, reg |
+ BCM89610_SHD_LEDS1_LED2(BCM_LED_SRC_LINKSPD1) |
+ BCM89610_SHD_LEDS1_LED1(BCM_LED_SRC_ACTIVITYLED));
+
+ reg = bcm_phy_read_shadow(phydev, BCM89610_SHD_LEDS2);
+ bcm_phy_write_shadow(phydev, BCM89610_SHD_LEDS2, reg |
+ BCM89610_SHD_LEDS2_LED3(BCM_LED_SRC_LINKSPD2));
bcm54xx_phydsp_config(phydev);
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index 4ede6b8..3dcd0c0 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -170,6 +170,14 @@
#define BCM5482_SHD_MODE 0x1f /* 11111: Mode Control Register */
#define BCM5482_SHD_MODE_1000BX 0x0001 /* Enable 1000BASE-X registers */
+#define BCM89610_SHD_LEDS1 0x0d
+#define BCM89610_SHD_LEDS1_LED2(src) ((src & 0xf) << 4)
+#define BCM89610_SHD_LEDS1_LED1(src) ((src & 0xf) << 0)
+
+#define BCM89610_SHD_LEDS2 0x0e
+#define BCM89610_SHD_LEDS2_LED4(src) ((src & 0xf) << 4)
+#define BCM89610_SHD_LEDS2_LED3(src) ((src & 0xf) << 0)
+
Hi WayneWWW
I try the patch, but it is not correct
Now The LED state is below
1000M : left link led : green ,but flashing
right speed led : yallow ,but flashing
1000M : left link led : green ,but flashing
right speed led : yallow ,but flashing
We want
1000M : left link led : orange ,on
right speed led : yellow
100M : left link led : green , on
right speed led : yellow
static int bcm54xx_config_init(struct phy_device *phydev)
{
int reg, err;
reg = phy_read(phydev, MII_BCM54XX_ECR);
if (reg < 0)
return reg;
/* Mask interrupts globally. */
reg |= MII_BCM54XX_ECR_IM;
err = phy_write(phydev, MII_BCM54XX_ECR, reg);
if (err < 0)
return err;
/* Unmask events we are interested in. */
reg = ~(MII_BCM54XX_INT_DUPLEX |
MII_BCM54XX_INT_SPEED |
MII_BCM54XX_INT_LINK |
MII_BCM54XX_INT_ANPR);
/* unmask energy detect interrupt */
if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM89610 ||
BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610)
reg &= ~MII_BCM54XX_INT_EDETECT;
err = phy_write(phydev, MII_BCM54XX_IMR, reg);
if (err < 0)
return err;
if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
(phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE))
bcm_phy_write_shadow(phydev, BCM54XX_SHD_RGMII_MODE, 0);
if ((phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) ||
(phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) ||
(phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
bcm54xx_adjust_rxrefclk(phydev);
/* enable energy detect interrupt status update */
if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM89610 ||
BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610) {
reg = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR3);
reg |= BCM54XX_SHD_SCR3_EDETECT_EN;
bcm_phy_write_shadow(phydev, BCM54XX_SHD_SCR3, reg);
bcm89xx_enable_oob(phydev);
/* Enable phy to tx/rx jumbo frames. Driver
* will drop jumbo frames if it is not enabled.
*/
reg = phy_read(phydev, MII_BCM54XX_ECR);
reg |= MII_BCM89XX_ECR_TXFIFOLAT;
err = phy_write(phydev, MII_BCM54XX_ECR, reg);
if (err < 0)
return err;
reg = bcm89xx_shadow_read(phydev, MII_BCM89XX_SHD_AUX_CONTROL);
reg |= BIT(14); /* Enable rx of extended pkts */
bcm89xx_shadow_write(phydev, MII_BCM89XX_SHD_AUX_CONTROL, reg);
/* Disable LOM-LED */
reg = bcm_phy_read_shadow(phydev, BCM54XX_SHD_RGMII_MODE);
reg = reg & ~(1 << 2);
reg = reg & ~(1 << 5);
reg = reg & ~(3);
bcm_phy_write_shadow(phydev, BCM54XX_SHD_RGMII_MODE, reg);
reg = bcm_phy_read_shadow(phydev, BCM89610_SHD_LEDS1);
bcm_phy_write_shadow(phydev, BCM89610_SHD_LEDS1, reg |
BCM89610_SHD_LEDS1_LED2(BCM_LED_SRC_LINKSPD2) |
BCM89610_SHD_LEDS1_LED1(BCM_LED_SRC_ACTIVITYLED));
reg = bcm_phy_read_shadow(phydev, BCM89610_SHD_LEDS2);
bcm_phy_write_shadow(phydev, BCM89610_SHD_LEDS1, reg |
BCM89610_SHD_LEDS2_LED3(BCM_LED_SRC_LINKSPD2));
/* disable AUTOEEEgr in TOP level expansion register 0x40
* as needed for Native EEE to work.
*/
err = bcm54xx_exp_read(phydev, MII_BCM54XX_TOPL_EXP_EXP40);
if (err < 0)
return err;
err &= ~MII_BCM54XX_TOPL_EXP_EXP40_AUTOGREEE;
err = bcm54xx_exp_write(phydev, MII_BCM54XX_TOPL_EXP_EXP40,
err);
if (err < 0)
return err;
}
bcm54xx_phydsp_config(phydev);
return 0;
}
/*
/* Broadcom IDDQ-LP regs */
#define MII_BCM54XX_SHD 0x1c
#define MII_BCM54XX_SHD_IDDQ 0x3000
#define MII_BCM54XX_IDDQ_LP 0x0001
#define MII_BCM54XX_EXT_CTL_WR_ENABLE 0X8000
#define BCM_IDDQ_EN 1
/* 01010: Auto Power-Down /
#define BCM54XX_SHD_APD 0x0a
#define BCM_APD_CLR_MASK 0xFE9F / clear bits 5, 6 & 8 /
#define BCM54XX_SHD_APD_EN 0x0020
#define BCM_NO_ANEG_APD_EN 0x0060 / bits 5 & 6 /
#define BCM_APD_SINGLELP_EN 0x0100 / Bit 8 */
#define BCM5482_SHD_LEDS1 0x0d /* 01101: LED Selector 1 /
/ LED3 / ~LINKSPD[2] selector /
#define BCM5482_SHD_LEDS1_LED3(src) ((src & 0xf) << 4)
/ LED1 / ~LINKSPD[1] selector /
#define BCM5482_SHD_LEDS1_LED1(src) ((src & 0xf) << 0)
#define BCM54XX_SHD_RGMII_MODE 0x0b / 01011: RGMII Mode Selector /
#define BCM5482_SHD_SSD 0x14 / 10100: Secondary SerDes control /
#define BCM5482_SHD_SSD_LEDM 0x0008 / SSD LED Mode enable /
#define BCM5482_SHD_SSD_EN 0x0001 / SSD enable /
#define BCM5482_SHD_MODE 0x1f / 11111: Mode Control Register /
#define BCM5482_SHD_MODE_1000BX 0x0001 / Enable 1000BASE-X registers */
#define BCM89610_SHD_LEDS1 0x0d
#define BCM89610_SHD_LEDS1_LED2(src) ((src & 0xf) << 4)
#define BCM89610_SHD_LEDS1_LED1(src) ((src & 0xf) << 0)
#define BCM89610_SHD_LEDS2 0x0e
#define BCM89610_SHD_LEDS2_LED4(src) ((src & 0xf) << 4)
#define BCM89610_SHD_LEDS2_LED3(src) ((src & 0xf) << 0)
Hi WayneWWW
I have already to follow your recommend, and Now The LED state is below
1000M : left link led : orange ,but flashing
right speed led : yallow ,but flashing
100M : left link led : orange ,but flashing
right speed led : yallow ,but flashing
Could you try to configure LED3 to Activity, LED2 to SPD2 and LED1 to SPD1?
hi WayneWWW
I don’t understand “try to configure LED3 to Activity, LED2 to SPD2 and LED1 to SPD1?”
thank
hi WayneWWW
how to rewrite code
bcm_phy_write_shadow(phydev, BCM54XX_SHD_RGMII_MODE, reg);
reg = bcm_phy_read_shadow(phydev, BCM89610_SHD_LEDS1);
bcm_phy_write_shadow(phydev, BCM89610_SHD_LEDS1, reg |
BCM89610_SHD_LEDS1_LED2(BCM_LED_SRC_LINKSPD2) |
BCM89610_SHD_LEDS1_LED1(BCM_LED_SRC_ACTIVITYLED));
reg = bcm_phy_read_shadow(phydev, BCM89610_SHD_LEDS2);
bcm_phy_write_shadow(phydev, BCM89610_SHD_LEDS1, reg |
BCM89610_SHD_LEDS2_LED3(BCM_LED_SRC_LINKSPD2));
BCM89610_SHD_LEDS2_LED3 → This means LED3, please try to modify the value in () to “BCM_LED_SRC_ACTIVITYLED”
and same manner to the other two.
BCM89610_SHD_LEDS1_LED2 → BCM_LED_SRC_LINKSPD2
BCM89610_SHD_LEDS1_LED1 → BCM_LED_SRC_LINKSPD1
/home/johnnyli/AIB-TX201/kernel/kernel-4.4/drivers/net/phy/broadcom.c: In function ‘bcm54xx_config_init’:
/home/johnnyli/AIB-TX201/kernel/kernel-4.4/drivers/net/phy/broadcom.c:546:84: error: called object is not a function or function pointer
bcm_phy_write_shadow(phydev, BCM89610_SHD_LEDS1, reg | BCM_LED_SRC_LINKSPD2(BCM_LED_SRC_LINKSPD1) | BCM_LED_SRC_LINKSPD1(BCM_LED_SRC_ACTIVITYLED));
^
/home/johnnyli/AIB-TX201/kernel/kernel-4.4/drivers/net/phy/broadcom.c:546:129: error: called object is not a function or function pointer
bcm_phy_write_shadow(phydev, BCM89610_SHD_LEDS1, reg | BCM_LED_SRC_LINKSPD2(BCM_LED_SRC_LINKSPD1) | BCM_LED_SRC_LINKSPD1(BCM_LED_SRC_ACTIVITYLED));
^
/home/johnnyli/AIB-TX201/kernel/kernel-4.4/scripts/Makefile.build:261: recipe for target ‘drivers/net/phy/broadcom.o’ failed
We are using kernel4.9 but not kernel4.4.
Hi WayneWWW
Is the version difference so big ?
if the answer is yes, can you provide for kernel 4.4 control Eth0 led way.
Hi aesinfo,
Are you using rel-28 release? I don’t get why you hit error in #14.
It is almost same change as you did in #7 and #8, but just swap the value to write into register. If you could make it in #7/8, why do you hit error in #14?
Also, I just read your code in #7 and #8 and they are not correct.
I guess the naming may cause trouble, so I would explain it again.
bcm_phy_write_shadow(phydev, BCM89610_SHD_LEDS1, reg |
BCM89610_SHD_LEDS1_LED2(BCM_LED_SRC_LINKSPD1) |
BCM89610_SHD_LEDS1_LED1(BCM_LED_SRC_ACTIVITYLED));
BCM89610_SHD_LEDS1 → This is the register address as 0x0d.
BCM89610_SHD_LEDS1_LED2 → This is a function for configuring LED2
BCM89610_SHD_LEDS1_LED1 → This is a function for configuring LED1
If I write BCM89610_SHD_LEDS1_LED2(BCM_LED_SRC_LINKSPD1), it means I configure LED2 as LINKSPD1 function.
Similar idea to BCM89610_SHD_LEDS1_LED1(BCM_LED_SRC_ACTIVITYLED) in which I configure LED1 to activity LED (the one that should be flashing).
LED1 and LED2 belong to register BCM89610_SHD_LEDS1 and LED3 and LED4 belong to BCM89610_SHD_LEDS2 (0x0e).
Thus, there would be no LED1 or LED2 appear to write to BCM89610_SHD_LEDS2.
In #13, I think we should configure
BCM89610_SHD_LEDS2_LED3 to activity led.
BCM89610_SHD_LEDS1_LED2 to BCM_LED_SRC_LINKSPD2
BCM89610_SHD_LEDS1_LED1 to BCM_LED_SRC_LINKSPD1
Please check if it can work.
Hi WayneWWW
As below is you provide example code. Can you tell me why i get error after you suggest.
/* Disable LOM-LED */
bcm_phy_write_shadow(phydev, BCM54XX_SHD_RGMII_MODE, reg);
reg = bcm_phy_read_shadow(phydev, BCM89610_SHD_LEDS1);
bcm_phy_write_shadow(phydev, BCM89610_SHD_LEDS1, reg |
[b]BCM89610_SHD_LEDS1_LED2[/b](BCM_LED_SRC_LINKSPD1) |
[b]BCM89610_SHD_LEDS1_LED1[/b](BCM_LED_SRC_ACTIVITYLED));
reg = bcm_phy_read_shadow(phydev, BCM89610_SHD_LEDS2);
bcm_phy_write_shadow(phydev, BCM89610_SHD_LEDS2, reg |
[b]BCM89610_SHD_LEDS2_LED3[/b](BCM_LED_SRC_LINKSPD2));
May I know what is the compilation error? Do you mean the code is not able to compile in the beginning?
export CROSS_COMPILE=/opt/l4t-gcc-toolchain-64-bit-28-2.1/install/bin/aarch64-unknown-linux-gnu-