Improve the identification rate of ETH cables

This commit is contained in:
某杰同学
2024-08-05 20:47:02 -07:00
parent 4bb531573b
commit 6be3e66437
2 changed files with 127 additions and 4 deletions

View File

@@ -793,7 +793,7 @@ static void stmmac_validate(struct phylink_config *config,
phylink_set(mac_supported, 10baseT_Half);
phylink_set(mac_supported, 10baseT_Full);
phylink_set(mac_supported, 100baseT_Half);
// phylink_set(mac_supported, 100baseT_Half);
phylink_set(mac_supported, 100baseT_Full);
phylink_set(mac_supported, 1000baseT_Half);
phylink_set(mac_supported, 1000baseT_Full);

View File

@@ -19,7 +19,8 @@
#define CVI_INT_EVENTS \
(CVI_LNK_STS_CHG_INT_MSK | CVI_MGC_PKT_DET_INT_MSK)
static u32 link_status;
static u32 retry_time;
static int cv182xa_phy_config_intr(struct phy_device *phydev)
{
return 0;
@@ -32,8 +33,117 @@ static int cv182xa_phy_ack_interrupt(struct phy_device *phydev)
static int cv182xa_read_status(struct phy_device *phydev)
{
int err = genphy_read_status(phydev);
u32 lp_val, lp_val_cap, cap_val, cap_val_temp, i, ramdom_cap;
u32 get_random;
static void __iomem *ADC3_register;
static void __iomem *ADC2_register;
if (!ADC3_register) {
ADC3_register = ioremap(0x030010F0, 0x8);
if (!ADC3_register)
pr_err("ioremap failed!!!");
ADC2_register = ADC3_register + 4;
}
int err = genphy_read_status(phydev);
// pr_notice("link status=%x, retry_time=%x\n", phydev->link, retry_time);
if (retry_time > 0)
retry_time--;
if (phydev->link == 0) {
if (retry_time == 0)
link_status = 0;
} else if (phydev->speed == SPEED_100 && link_status == 0) {
link_status = 1;
lp_val = phy_read(phydev, 0x5);
pr_err("lp1=%x\n", lp_val);
if (phydev->autoneg == AUTONEG_ENABLE && lp_val == 0x4d61) {
cap_val = phy_read(phydev, 0x4);
pr_notice("cap1=%x\n", cap_val);
get_random_bytes(&get_random, sizeof(int32_t));
//ramdom_cap = (get_random % 13) << 5;
//if(ramdom_cap == 0x160)
//{
// ramdom_cap = 0x1e0;
//}
//cap_val_temp = cap_val & ~0x1e0 | ramdom_cap;
ramdom_cap = get_random & 0xde0 | 0x20;
if (ramdom_cap == 0xd60) {
pr_notice("ramdom_cap=%x\n\n", ramdom_cap);
ramdom_cap = 0xde0;
}
cap_val_temp = cap_val & ~0xde0 | ramdom_cap;
phy_write(phydev, 0x4, cap_val_temp);
pr_notice("get_random=%x, ramdom_cap=%x, cap_val_temp=%x\n",
get_random, ramdom_cap, cap_val_temp);
for (i = 0; i < 150; i++) {
if ((phy_read(phydev, 0x1) & 0x20) == 0)
break;
mdelay(10);
}
pr_notice("i=%d\n", i);
phy_modify(phydev, MII_BMCR, BMCR_ISOLATE, BMCR_ANENABLE | BMCR_ANRESTART);
for (i = 0; i < 1000; i++) {
if (phy_read(phydev, 0x1) & 0x20)
break;
mdelay(10);
}
lp_val = phy_read(phydev, 0x5);
lp_val_cap = lp_val & 0xde0;
pr_notice(" %d, link status=%x, lp2=%x\n", i, phy_read(phydev, 0x1), lp_val);
if (((phy_read(phydev, 0x1) & 0x4) != 0) && lp_val != 0 && lp_val_cap != ramdom_cap) {
retry_time = 10;
phy_write(phydev, 0x4, cap_val);
phy_modify(phydev, MII_BMCR, BMCR_ISOLATE, BMCR_ANENABLE | BMCR_ANRESTART);
for (i = 0; i < 1000; i++) {
if (phy_read(phydev, 0x1) & 0x20)
break;
mdelay(10);
}
//mdelay(8000);
//lp_val = phy_read(phydev, 0x5);
pr_notice(" %d, true link status=%x, lp2=%x\n", i,
phy_read(phydev, 0x1), phy_read(phydev, 0x5));
} else {
phydev->link = 0;
link_status = 0;
phy_write(phydev, 0x4, cap_val);
phy_modify(phydev, MII_BMCR, BMCR_ISOLATE, BMCR_ANENABLE | BMCR_ANRESTART);
//err = phy_start_aneg(phydev);
//lp_val = phy_read(phydev, 0x5);
//pr_notice("lp3=%x\n", lp_val);
pr_notice(" %d, false link status=%x, lp2=%x\n", i,
phy_read(phydev, 0x1), phy_read(phydev, 0x5));
}
//err = genphy_read_status(phydev);
//lp_val = phy_read(phydev, 0x5);
//pr_notice("lp3=%x\n", lp_val);
}
}
if (phydev->speed == SPEED_100) {
phy_write(phydev, 0x1f, 0x100);
if (phydev->link == 0) {
// select LED_LNK/SPD/DPX out to LED_PAD
phy_write(phydev, 0x1a, phy_read(phydev, 0x1a) | 0xf00);
if (ADC3_register) {
writel(0x3, ADC2_register);
writel(0x3, ADC3_register);
}
} else {
if (ADC3_register) {
writel(0x5, ADC2_register);
writel(0x5, ADC3_register);
}
phy_write(phydev, 0x1a, phy_read(phydev, 0x1a) & ~0xf00);
}
phy_write(phydev, 0x1f, 0x0);
}
pr_debug("%s, speed=%d, duplex=%d, ", __func__, phydev->speed, phydev->duplex);
pr_debug("pasue=%d, asym_pause=%d, autoneg=%d ", phydev->pause, phydev->asym_pause, phydev->autoneg);
@@ -211,7 +321,7 @@ static int cv182xa_phy_config_init(struct phy_device *phydev)
writel(0x8688, reg_ephy_base + 0x68);
writel(0x8484, reg_ephy_base + 0x6c);
writel(0x0082, reg_ephy_base + 0x70);
#else
#else
// from sean
// Fix err: the status is still linkup when removed the network cable.
writel(0x2000, reg_ephy_base + 0x40);
@@ -296,6 +406,17 @@ static int cv182xa_phy_config_init(struct phy_device *phydev)
// select LED_LNK/SPD/DPX out to LED_PAD
writel((readl(reg_ephy_base + 0x68) & ~0x0f00), reg_ephy_base + 0x68);
// led pol
// Switch to MII-page0
writel(0x0, reg_ephy_base + 0x7c);
// printk(KERN_EMERG "ethernet: reg_ephy_base + 0x4c %lx\n",readl(reg_ephy_base + 0x4c));
// printk(KERN_EMERG "---------------\n");
// h13 10~8 LED polarity invert, 0(high-active),1(low-active)
writel((readl(reg_ephy_base + 0x4c) | 0x0700), reg_ephy_base + 0x4c);
//printk("ethernet: reg_ephy_base + 0x4c %lx\n\n\n",readl(reg_ephy_base + 0x4c));
// printk(KERN_EMERG "---------------\n");
// Switch to MII-page19
writel(0x1300, reg_ephy_base + 0x7c);
writel(0x0012, reg_ephy_base + 0x58);
@@ -336,6 +457,8 @@ static int cv182xa_phy_config_init(struct phy_device *phydev)
// switch to MDIO control by ETH_MAC
writel(0x0000, reg_ephy_top_wrap + 4);
link_status = 0;
retry_time = 0;
iounmap(reg_ephy_base);
err_ephy_mem_2:
iounmap(reg_ephy_top_wrap);