Message ID | 20221020094106.559266-2-andy.chiu@sifive.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | net:axienet: Add a DT property to configure frequency of the MDIO bus | expand |
Hi, Am Donnerstag, 20. Oktober 2022, 11:41:05 CEST schrieb Andy Chiu: > Some FPGA platforms has 80KHz MDIO bus frequency constraint when > conecting Ethernet to its on-board external Marvell PHY. Thus, we may > have to set MDIO clock according to the DT. Otherwise, use the default > 2.5 MHz, as specified by 802.3, if the entry is not present. > > Signed-off-by: Andy Chiu <andy.chiu@sifive.com> > Reviewed-by: Greentime Hu <greentime.hu@sifive.com> > --- > .../net/ethernet/xilinx/xilinx_axienet_mdio.c | 25 ++++++++++++++++--- > 1 file changed, 21 insertions(+), 4 deletions(-) > > diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c > b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c index > 0b3b6935c558..d07c39d3bcf0 100644 > --- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c > +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c > @@ -18,6 +18,7 @@ > #include "xilinx_axienet.h" > > #define MAX_MDIO_FREQ 2500000 /* 2.5 MHz */ > +#define MDIO_CLK_DIV_MASK 0x3f /* bits[5:0] */ > #define DEFAULT_HOST_CLOCK 150000000 /* 150 MHz */ > > /* Wait till MDIO interface is ready to accept a new transaction.*/ > @@ -155,7 +156,9 @@ static int axienet_mdio_write(struct mii_bus *bus, int > phy_id, int reg, **/ > int axienet_mdio_enable(struct axienet_local *lp) > { > + u32 clk_div; > u32 host_clock; > + u32 mdio_freq; > > lp->mii_clk_div = 0; > > @@ -184,6 +187,13 @@ int axienet_mdio_enable(struct axienet_local *lp) > host_clock); > } > > + if (of_property_read_u32(lp->dev->of_node, "xlnx,mdio-freq", > + &mdio_freq)) { > + mdio_freq = MAX_MDIO_FREQ; > + netdev_info(lp->ndev, "Setting default mdio clock to %u\n", > + mdio_freq); I would opt to print this message only if using non-default frequency. Best regards, Alexander > + } > + > /* clk_div can be calculated by deriving it from the equation: > * fMDIO = fHOST / ((1 + clk_div) * 2) > * > @@ -209,13 +219,20 @@ int axienet_mdio_enable(struct axienet_local *lp) > * "clock-frequency" from the CPU > */ > > - lp->mii_clk_div = (host_clock / (MAX_MDIO_FREQ * 2)) - 1; > + clk_div = (host_clock / (mdio_freq * 2)) - 1; > /* If there is any remainder from the division of > - * fHOST / (MAX_MDIO_FREQ * 2), then we need to add > + * fHOST / (mdio_freq * 2), then we need to add > * 1 to the clock divisor or we will surely be above 2.5 MHz > */ > - if (host_clock % (MAX_MDIO_FREQ * 2)) > - lp->mii_clk_div++; > + if (host_clock % (mdio_freq * 2)) > + clk_div++; > + > + /* Check for overflow of mii_clk_div */ > + if (clk_div & ~MDIO_CLK_DIV_MASK) { > + netdev_dbg(lp->ndev, "MDIO clock divisor overflow, setting to maximum > value\n"); + clk_div = MDIO_CLK_DIV_MASK; > + } > + lp->mii_clk_div = (u8)clk_div; > > netdev_dbg(lp->ndev, > "Setting MDIO clock divisor to %u/%u Hz host clock. \n",
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c index 0b3b6935c558..d07c39d3bcf0 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c @@ -18,6 +18,7 @@ #include "xilinx_axienet.h" #define MAX_MDIO_FREQ 2500000 /* 2.5 MHz */ +#define MDIO_CLK_DIV_MASK 0x3f /* bits[5:0] */ #define DEFAULT_HOST_CLOCK 150000000 /* 150 MHz */ /* Wait till MDIO interface is ready to accept a new transaction.*/ @@ -155,7 +156,9 @@ static int axienet_mdio_write(struct mii_bus *bus, int phy_id, int reg, **/ int axienet_mdio_enable(struct axienet_local *lp) { + u32 clk_div; u32 host_clock; + u32 mdio_freq; lp->mii_clk_div = 0; @@ -184,6 +187,13 @@ int axienet_mdio_enable(struct axienet_local *lp) host_clock); } + if (of_property_read_u32(lp->dev->of_node, "xlnx,mdio-freq", + &mdio_freq)) { + mdio_freq = MAX_MDIO_FREQ; + netdev_info(lp->ndev, "Setting default mdio clock to %u\n", + mdio_freq); + } + /* clk_div can be calculated by deriving it from the equation: * fMDIO = fHOST / ((1 + clk_div) * 2) * @@ -209,13 +219,20 @@ int axienet_mdio_enable(struct axienet_local *lp) * "clock-frequency" from the CPU */ - lp->mii_clk_div = (host_clock / (MAX_MDIO_FREQ * 2)) - 1; + clk_div = (host_clock / (mdio_freq * 2)) - 1; /* If there is any remainder from the division of - * fHOST / (MAX_MDIO_FREQ * 2), then we need to add + * fHOST / (mdio_freq * 2), then we need to add * 1 to the clock divisor or we will surely be above 2.5 MHz */ - if (host_clock % (MAX_MDIO_FREQ * 2)) - lp->mii_clk_div++; + if (host_clock % (mdio_freq * 2)) + clk_div++; + + /* Check for overflow of mii_clk_div */ + if (clk_div & ~MDIO_CLK_DIV_MASK) { + netdev_dbg(lp->ndev, "MDIO clock divisor overflow, setting to maximum value\n"); + clk_div = MDIO_CLK_DIV_MASK; + } + lp->mii_clk_div = (u8)clk_div; netdev_dbg(lp->ndev, "Setting MDIO clock divisor to %u/%u Hz host clock.\n",