Skip to content

Commit

Permalink
Merge pull request #2750 from cesanta/gbephy
Browse files Browse the repository at this point in the history
fix LAN87x
  • Loading branch information
scaprile authored May 13, 2024
2 parents 50963df + 81f0f8a commit 3ae1a0f
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 34 deletions.
23 changes: 6 additions & 17 deletions mongoose.c
Original file line number Diff line number Diff line change
Expand Up @@ -15624,31 +15624,21 @@ static const char *mg_phy_id_to_str(uint16_t id1, uint16_t id2) {
(void) id2;
}

static void mg_phy_set_clk_out(struct mg_phy *phy, uint8_t phy_addr) {
uint16_t id1, id2;
id1 = phy->read_reg(phy_addr, MG_PHY_REG_ID1);
id2 = phy->read_reg(phy_addr, MG_PHY_REG_ID2);

if (id1 == MG_PHY_DP83x && id2 == MG_PHY_DP83867) {
// write 0x10d to IO_MUX_CFG (0x0170)
phy->write_reg(phy_addr, 0x0d, 0x1f);
phy->write_reg(phy_addr, 0x0e, 0x170);
phy->write_reg(phy_addr, 0x0d, 0x401f);
phy->write_reg(phy_addr, 0x0e, 0x10d);
}
}

void mg_phy_init(struct mg_phy *phy, uint8_t phy_addr, uint8_t config) {
uint16_t id1, id2;
phy->write_reg(phy_addr, MG_PHY_REG_BCR, MG_BIT(15)); // Reset PHY
phy->write_reg(phy_addr, MG_PHY_REG_BCR, MG_BIT(12)); // Autonegotiation
while (phy->read_reg(phy_addr, MG_PHY_REG_BCR) & MG_BIT(15)) (void) 0;
// MG_PHY_REG_BCR[12]: Autonegotiation is default unless hw says otherwise

id1 = phy->read_reg(phy_addr, MG_PHY_REG_ID1);
id2 = phy->read_reg(phy_addr, MG_PHY_REG_ID2);
MG_INFO(("PHY ID: %#04x %#04x (%s)", id1, id2, mg_phy_id_to_str(id1, id2)));

if (id1 == MG_PHY_DP83x && id2 == MG_PHY_DP83867) {
mg_phy_set_clk_out(phy, phy_addr);
phy->write_reg(phy_addr, 0x0d, 0x1f); // write 0x10d to IO_MUX_CFG (0x0170)
phy->write_reg(phy_addr, 0x0e, 0x170);
phy->write_reg(phy_addr, 0x0d, 0x401f);
phy->write_reg(phy_addr, 0x0e, 0x10d);
}

if (config & MG_PHY_CLOCKS_MAC) {
Expand Down Expand Up @@ -15711,7 +15701,6 @@ bool mg_phy_up(struct mg_phy *phy, uint8_t phy_addr, bool *full_duplex,
*speed = (scsr & MG_BIT(3)) ? MG_PHY_SPEED_100M : MG_PHY_SPEED_10M;
} else if (id1 == MG_PHY_RTL8201) {
uint16_t bcr = phy->read_reg(phy_addr, MG_PHY_REG_BCR);
if (bcr & MG_BIT(15)) return 0; // still resetting
*full_duplex = bcr & MG_BIT(8);
*speed = (bcr & MG_BIT(13)) ? MG_PHY_SPEED_100M : MG_PHY_SPEED_10M;
}
Expand Down
23 changes: 6 additions & 17 deletions src/drivers/phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,31 +45,21 @@ static const char *mg_phy_id_to_str(uint16_t id1, uint16_t id2) {
(void) id2;
}

static void mg_phy_set_clk_out(struct mg_phy *phy, uint8_t phy_addr) {
uint16_t id1, id2;
id1 = phy->read_reg(phy_addr, MG_PHY_REG_ID1);
id2 = phy->read_reg(phy_addr, MG_PHY_REG_ID2);

if (id1 == MG_PHY_DP83x && id2 == MG_PHY_DP83867) {
// write 0x10d to IO_MUX_CFG (0x0170)
phy->write_reg(phy_addr, 0x0d, 0x1f);
phy->write_reg(phy_addr, 0x0e, 0x170);
phy->write_reg(phy_addr, 0x0d, 0x401f);
phy->write_reg(phy_addr, 0x0e, 0x10d);
}
}

void mg_phy_init(struct mg_phy *phy, uint8_t phy_addr, uint8_t config) {
uint16_t id1, id2;
phy->write_reg(phy_addr, MG_PHY_REG_BCR, MG_BIT(15)); // Reset PHY
phy->write_reg(phy_addr, MG_PHY_REG_BCR, MG_BIT(12)); // Autonegotiation
while (phy->read_reg(phy_addr, MG_PHY_REG_BCR) & MG_BIT(15)) (void) 0;
// MG_PHY_REG_BCR[12]: Autonegotiation is default unless hw says otherwise

id1 = phy->read_reg(phy_addr, MG_PHY_REG_ID1);
id2 = phy->read_reg(phy_addr, MG_PHY_REG_ID2);
MG_INFO(("PHY ID: %#04x %#04x (%s)", id1, id2, mg_phy_id_to_str(id1, id2)));

if (id1 == MG_PHY_DP83x && id2 == MG_PHY_DP83867) {
mg_phy_set_clk_out(phy, phy_addr);
phy->write_reg(phy_addr, 0x0d, 0x1f); // write 0x10d to IO_MUX_CFG (0x0170)
phy->write_reg(phy_addr, 0x0e, 0x170);
phy->write_reg(phy_addr, 0x0d, 0x401f);
phy->write_reg(phy_addr, 0x0e, 0x10d);
}

if (config & MG_PHY_CLOCKS_MAC) {
Expand Down Expand Up @@ -132,7 +122,6 @@ bool mg_phy_up(struct mg_phy *phy, uint8_t phy_addr, bool *full_duplex,
*speed = (scsr & MG_BIT(3)) ? MG_PHY_SPEED_100M : MG_PHY_SPEED_10M;
} else if (id1 == MG_PHY_RTL8201) {
uint16_t bcr = phy->read_reg(phy_addr, MG_PHY_REG_BCR);
if (bcr & MG_BIT(15)) return 0; // still resetting
*full_duplex = bcr & MG_BIT(8);
*speed = (bcr & MG_BIT(13)) ? MG_PHY_SPEED_100M : MG_PHY_SPEED_10M;
}
Expand Down

0 comments on commit 3ae1a0f

Please sign in to comment.