Skip to content

Commit 1446087

Browse files
committed
net: stmmac: Separate C22 and C45 transactions for xgmac
jira LE-1907 Rebuild_History Non-Buildable kernel-5.14.0-427.40.1.el9_4 commit-author Andrew Lunn <andrew@lunn.ch> commit 3c7826d The stmmac MDIO bus driver in variant gmac4 can perform both C22 and C45 transfers. Create separate functions for each and register the C45 versions using the new API calls where appropriate. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Michael Walle <michael@walle.cc> Signed-off-by: Jakub Kicinski <kuba@kernel.org> (cherry picked from commit 3c7826d) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
1 parent 7d9c3f9 commit 1446087

File tree

1 file changed

+138
-62
lines changed

1 file changed

+138
-62
lines changed

drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c

Lines changed: 138 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,29 @@ static int stmmac_xgmac2_mdio_write_c45(struct mii_bus *bus, int phyaddr,
234234
phydata);
235235
}
236236

237+
static int stmmac_mdio_read(struct stmmac_priv *priv, int data, u32 value)
238+
{
239+
unsigned int mii_address = priv->hw->mii.addr;
240+
unsigned int mii_data = priv->hw->mii.data;
241+
u32 v;
242+
243+
if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
244+
100, 10000))
245+
return -EBUSY;
246+
247+
writel(data, priv->ioaddr + mii_data);
248+
writel(value, priv->ioaddr + mii_address);
249+
250+
if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
251+
100, 10000))
252+
return -EBUSY;
253+
254+
/* Read the data from the MII data register */
255+
return readl(priv->ioaddr + mii_data) & MII_DATA_MASK;
256+
}
257+
237258
/**
238-
* stmmac_mdio_read
259+
* stmmac_mdio_read_c22
239260
* @bus: points to the mii_bus structure
240261
* @phyaddr: MII addr
241262
* @phyreg: MII reg
@@ -244,15 +265,12 @@ static int stmmac_xgmac2_mdio_write_c45(struct mii_bus *bus, int phyaddr,
244265
* accessing the PHY registers.
245266
* Fortunately, it seems this has no drawback for the 7109 MAC.
246267
*/
247-
static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
268+
static int stmmac_mdio_read_c22(struct mii_bus *bus, int phyaddr, int phyreg)
248269
{
249270
struct net_device *ndev = bus->priv;
250271
struct stmmac_priv *priv = netdev_priv(ndev);
251-
unsigned int mii_address = priv->hw->mii.addr;
252-
unsigned int mii_data = priv->hw->mii.data;
253272
u32 value = MII_BUSY;
254273
int data = 0;
255-
u32 v;
256274

257275
data = pm_runtime_resume_and_get(priv->device);
258276
if (data < 0)
@@ -265,60 +283,94 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
265283
& priv->hw->mii.clk_csr_mask;
266284
if (priv->plat->has_gmac4) {
267285
value |= MII_GMAC4_READ;
268-
if (phyreg & MII_ADDR_C45) {
269-
value |= MII_GMAC4_C45E;
270-
value &= ~priv->hw->mii.reg_mask;
271-
value |= ((phyreg >> MII_DEVADDR_C45_SHIFT) <<
272-
priv->hw->mii.reg_shift) &
273-
priv->hw->mii.reg_mask;
274-
275-
data |= (phyreg & MII_REGADDR_C45_MASK) <<
276-
MII_GMAC4_REG_ADDR_SHIFT;
277-
}
278286
}
279287

280-
if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
281-
100, 10000)) {
282-
data = -EBUSY;
283-
goto err_disable_clks;
284-
}
288+
data = stmmac_mdio_read(priv, data, value);
285289

286-
writel(data, priv->ioaddr + mii_data);
287-
writel(value, priv->ioaddr + mii_address);
290+
pm_runtime_put(priv->device);
288291

289-
if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
290-
100, 10000)) {
291-
data = -EBUSY;
292-
goto err_disable_clks;
292+
return data;
293+
}
294+
295+
/**
296+
* stmmac_mdio_read_c45
297+
* @bus: points to the mii_bus structure
298+
* @phyaddr: MII addr
299+
* @devad: device address to read
300+
* @phyreg: MII reg
301+
* Description: it reads data from the MII register from within the phy device.
302+
* For the 7111 GMAC, we must set the bit 0 in the MII address register while
303+
* accessing the PHY registers.
304+
* Fortunately, it seems this has no drawback for the 7109 MAC.
305+
*/
306+
static int stmmac_mdio_read_c45(struct mii_bus *bus, int phyaddr, int devad,
307+
int phyreg)
308+
{
309+
struct net_device *ndev = bus->priv;
310+
struct stmmac_priv *priv = netdev_priv(ndev);
311+
u32 value = MII_BUSY;
312+
int data = 0;
313+
314+
data = pm_runtime_get_sync(priv->device);
315+
if (data < 0) {
316+
pm_runtime_put_noidle(priv->device);
317+
return data;
293318
}
294319

295-
/* Read the data from the MII data register */
296-
data = (int)readl(priv->ioaddr + mii_data) & MII_DATA_MASK;
320+
value |= (phyaddr << priv->hw->mii.addr_shift)
321+
& priv->hw->mii.addr_mask;
322+
value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
323+
value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
324+
& priv->hw->mii.clk_csr_mask;
325+
value |= MII_GMAC4_READ;
326+
value |= MII_GMAC4_C45E;
327+
value &= ~priv->hw->mii.reg_mask;
328+
value |= (devad << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
329+
330+
data |= phyreg << MII_GMAC4_REG_ADDR_SHIFT;
331+
332+
data = stmmac_mdio_read(priv, data, value);
297333

298-
err_disable_clks:
299334
pm_runtime_put(priv->device);
300335

301336
return data;
302337
}
303338

339+
static int stmmac_mdio_write(struct stmmac_priv *priv, int data, u32 value)
340+
{
341+
unsigned int mii_address = priv->hw->mii.addr;
342+
unsigned int mii_data = priv->hw->mii.data;
343+
u32 v;
344+
345+
/* Wait until any existing MII operation is complete */
346+
if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
347+
100, 10000))
348+
return -EBUSY;
349+
350+
/* Set the MII address register to write */
351+
writel(data, priv->ioaddr + mii_data);
352+
writel(value, priv->ioaddr + mii_address);
353+
354+
/* Wait until any existing MII operation is complete */
355+
return readl_poll_timeout(priv->ioaddr + mii_address, v,
356+
!(v & MII_BUSY), 100, 10000);
357+
}
358+
304359
/**
305-
* stmmac_mdio_write
360+
* stmmac_mdio_write_c22
306361
* @bus: points to the mii_bus structure
307362
* @phyaddr: MII addr
308363
* @phyreg: MII reg
309364
* @phydata: phy data
310365
* Description: it writes the data into the MII register from within the device.
311366
*/
312-
static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
313-
u16 phydata)
367+
static int stmmac_mdio_write_c22(struct mii_bus *bus, int phyaddr, int phyreg,
368+
u16 phydata)
314369
{
315370
struct net_device *ndev = bus->priv;
316371
struct stmmac_priv *priv = netdev_priv(ndev);
317-
unsigned int mii_address = priv->hw->mii.addr;
318-
unsigned int mii_data = priv->hw->mii.data;
319372
int ret, data = phydata;
320373
u32 value = MII_BUSY;
321-
u32 v;
322374

323375
ret = pm_runtime_resume_and_get(priv->device);
324376
if (ret < 0)
@@ -330,38 +382,57 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
330382

331383
value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
332384
& priv->hw->mii.clk_csr_mask;
333-
if (priv->plat->has_gmac4) {
385+
if (priv->plat->has_gmac4)
334386
value |= MII_GMAC4_WRITE;
335-
if (phyreg & MII_ADDR_C45) {
336-
value |= MII_GMAC4_C45E;
337-
value &= ~priv->hw->mii.reg_mask;
338-
value |= ((phyreg >> MII_DEVADDR_C45_SHIFT) <<
339-
priv->hw->mii.reg_shift) &
340-
priv->hw->mii.reg_mask;
341-
342-
data |= (phyreg & MII_REGADDR_C45_MASK) <<
343-
MII_GMAC4_REG_ADDR_SHIFT;
344-
}
345-
} else {
387+
else
346388
value |= MII_WRITE;
347-
}
348389

349-
/* Wait until any existing MII operation is complete */
350-
if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
351-
100, 10000)) {
352-
ret = -EBUSY;
353-
goto err_disable_clks;
390+
ret = stmmac_mdio_write(priv, data, value);
391+
392+
pm_runtime_put(priv->device);
393+
394+
return ret;
395+
}
396+
397+
/**
398+
* stmmac_mdio_write_c45
399+
* @bus: points to the mii_bus structure
400+
* @phyaddr: MII addr
401+
* @phyreg: MII reg
402+
* @devad: device address to read
403+
* @phydata: phy data
404+
* Description: it writes the data into the MII register from within the device.
405+
*/
406+
static int stmmac_mdio_write_c45(struct mii_bus *bus, int phyaddr,
407+
int devad, int phyreg, u16 phydata)
408+
{
409+
struct net_device *ndev = bus->priv;
410+
struct stmmac_priv *priv = netdev_priv(ndev);
411+
int ret, data = phydata;
412+
u32 value = MII_BUSY;
413+
414+
ret = pm_runtime_get_sync(priv->device);
415+
if (ret < 0) {
416+
pm_runtime_put_noidle(priv->device);
417+
return ret;
354418
}
355419

356-
/* Set the MII address register to write */
357-
writel(data, priv->ioaddr + mii_data);
358-
writel(value, priv->ioaddr + mii_address);
420+
value |= (phyaddr << priv->hw->mii.addr_shift)
421+
& priv->hw->mii.addr_mask;
422+
value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
359423

360-
/* Wait until any existing MII operation is complete */
361-
ret = readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
362-
100, 10000);
424+
value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
425+
& priv->hw->mii.clk_csr_mask;
426+
427+
value |= MII_GMAC4_WRITE;
428+
value |= MII_GMAC4_C45E;
429+
value &= ~priv->hw->mii.reg_mask;
430+
value |= (devad << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
431+
432+
data |= phyreg << MII_GMAC4_REG_ADDR_SHIFT;
433+
434+
ret = stmmac_mdio_write(priv, data, value);
363435

364-
err_disable_clks:
365436
pm_runtime_put(priv->device);
366437

367438
return ret;
@@ -499,8 +570,13 @@ int stmmac_mdio_register(struct net_device *ndev)
499570
dev_err(dev, "Unsupported phy_addr (max=%d)\n",
500571
MII_XGMAC_MAX_C22ADDR);
501572
} else {
502-
new_bus->read = &stmmac_mdio_read;
503-
new_bus->write = &stmmac_mdio_write;
573+
new_bus->read = &stmmac_mdio_read_c22;
574+
new_bus->write = &stmmac_mdio_write_c22;
575+
if (priv->plat->has_gmac4) {
576+
new_bus->read_c45 = &stmmac_mdio_read_c45;
577+
new_bus->write_c45 = &stmmac_mdio_write_c45;
578+
}
579+
504580
max_addr = PHY_MAX_ADDR;
505581
}
506582

0 commit comments

Comments
 (0)