Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/port/amd/common/gem.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
*/
int amd_eth_init(struct wolfIP_ll_dev *ll);

/* Finishes bring-up when the PHY driver was built not to block on the link
* (GEM_PHY_*_TIMEOUT_MS = 0): poll until link up, which also programs the MAC
* speed. Returns 1 up, 0 down, < 0 on MDIO error. */
int gem_link_resolve(void);

/* MDIO helpers exposed for the PHY drivers. */
int gem_mdio_read(uint8_t phy_addr, uint8_t reg, uint16_t *out);
int gem_mdio_write(uint8_t phy_addr, uint8_t reg, uint16_t value);
Expand Down
63 changes: 48 additions & 15 deletions src/port/amd/common/gem_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,36 @@ void gem_dump_state(void)
/* ---------------------------------------------------------------------
* Public init
* ------------------------------------------------------------------- */
/* Set once a downshift has moved the reference clock off the platform's rate. */
static int gem_ref_clk_downshifted = 0;

/* Program the MAC for a resolved speed and duplex. Writes the whole field, not
* a relative clear: gem_link_resolve() can reach this more than once. */
static void gem_set_mac_speed(int speed, int fd)
{
uint32_t cfg = GEM_NWCFG;

cfg &= ~(NWCFG_1000 | NWCFG_SPEED100 | NWCFG_FDEN);
if (speed == 1000)
cfg |= NWCFG_1000;
else if (speed == 100)
cfg |= NWCFG_SPEED100;
if (fd)
cfg |= NWCFG_FDEN;
GEM_NWCFG = cfg;

/* Gigabit must not rewrite the clock until a downshift has moved it: that
* rate is the platform's, and under SGMII the serdes owns it. */
if (speed != 1000) {
gem_set_ref_clk(speed);
gem_ref_clk_downshifted = 1;
}
else if (gem_ref_clk_downshifted) {
gem_set_ref_clk(1000);
gem_ref_clk_downshifted = 0;
}
}

int amd_eth_init(struct wolfIP_ll_dev *ll)
{
#ifndef GEM_PHY_ADDR
Expand Down Expand Up @@ -462,21 +492,7 @@ int amd_eth_init(struct wolfIP_ll_dev *ll)
return -11;
}

/* If PHY ended up at 10/100, downshift the MAC and re-program the
* RGMII reference clock to match (no-op on SoCs where the platform
* firmware owns the GEM clock). */
if (speed != 1000) {
uint32_t cfg = GEM_NWCFG;
cfg &= ~NWCFG_1000;
if (speed == 100)
cfg |= NWCFG_SPEED100;
else
cfg &= ~NWCFG_SPEED100;
if (!fd)
cfg &= ~NWCFG_FDEN;
GEM_NWCFG = cfg;
gem_set_ref_clk(speed);
}
gem_set_mac_speed(speed, fd);

#ifdef ZYNQMP_GEM_SGMII
/* Bring up the PCS side. A MAC-to-PHY SGMII connection is normally a
Expand Down Expand Up @@ -544,3 +560,20 @@ int amd_eth_init(struct wolfIP_ll_dev *ll)
link_up = (gem_phy_link_status(gem_phy_addr) == 1) ? 1 : 0;
return (link_up << 8) | (int)gem_phy_addr;
}

int gem_link_resolve(void)
{
int link;
int speed = 1000;
int fd = 1;

link = gem_phy_link_status(gem_phy_addr);
if (link <= 0) {
return link;
}
if (gem_phy_link_speed(gem_phy_addr, &speed, &fd) < 0) {
return -1;
}
gem_set_mac_speed(speed, fd);
return 1;
}
1 change: 1 addition & 0 deletions src/port/amd/common/gem_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ void gem_set_ref_clk(int speed_mbps); /* RGMII TX clock for link speed */
* the MDIO scan; sets *speed (10/100/1000) and *fd; returns 0 / <0. --- */
int gem_phy_init(uint8_t phy_addr, uint16_t id1, int *speed, int *full_duplex);
int gem_phy_link_status(uint8_t phy_addr);
int gem_phy_link_speed(uint8_t phy_addr, int *speed, int *full_duplex);

/* --- RX delivery model (ip/gem_rx_*.c) --- */
void gem_rx_install(void); /* arm the RX path (install IRQ, or mask) */
Expand Down
5 changes: 5 additions & 0 deletions src/port/amd/ip/phy_dispatch_dp83867.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ int gem_phy_link_status(uint8_t phy_addr)
{
return dp83867_link_status(phy_addr);
}

int gem_phy_link_speed(uint8_t phy_addr, int *speed, int *full_duplex)
{
return dp83867_link_speed(phy_addr, speed, full_duplex);
}
7 changes: 7 additions & 0 deletions src/port/amd/ip/phy_dispatch_multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,10 @@ int gem_phy_link_status(uint8_t phy_addr)
/* Generic clause-22 BMSR read works for both PHYs. */
return dp83867_link_status(phy_addr);
}

int gem_phy_link_speed(uint8_t phy_addr, int *speed, int *full_duplex)
{
/* Falls back to clause-22 on a part it does not recognize, as the Marvell
* needs. */
return dp83867_link_speed(phy_addr, speed, full_duplex);
}
Loading
Loading