Skip to content

Commit 7f85442

Browse files
lunndavem330
authored andcommitted
phy: Add API for {un}registering an mdio device to a bus.
Rather than have drivers directly manipulate the mii_bus structure, provide and API for registering and unregistering devices on an MDIO bus, and performing lookups. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 801a8ef commit 7f85442

File tree

17 files changed

+98
-49
lines changed

17 files changed

+98
-49
lines changed

drivers/net/ethernet/amd/au1000_eth.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ static int au1000_mii_probe(struct net_device *dev)
502502
BUG_ON(aup->mac_id < 0 || aup->mac_id > 1);
503503

504504
if (aup->phy_addr)
505-
phydev = aup->mii_bus->phy_map[aup->phy_addr];
505+
phydev = mdiobus_get_phy(aup->mii_bus, aup->phy_addr);
506506
else
507507
netdev_info(dev, "using PHY-less setup\n");
508508
return 0;
@@ -512,8 +512,8 @@ static int au1000_mii_probe(struct net_device *dev)
512512
* on the current MAC's MII bus
513513
*/
514514
for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++)
515-
if (aup->mii_bus->phy_map[phy_addr]) {
516-
phydev = aup->mii_bus->phy_map[phy_addr];
515+
if (mdiobus_get_phy(aup->mii_bus, aup->phy_addr)) {
516+
phydev = mdiobus_get_phy(aup->mii_bus, aup->phy_addr);
517517
if (!aup->phy_search_highest_addr)
518518
/* break out with first one found */
519519
break;
@@ -531,7 +531,8 @@ static int au1000_mii_probe(struct net_device *dev)
531531
*/
532532
for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
533533
struct phy_device *const tmp_phydev =
534-
aup->mii_bus->phy_map[phy_addr];
534+
mdiobus_get_phy(aup->mii_bus,
535+
phy_addr);
535536

536537
if (aup->mac_id == 1)
537538
break;

drivers/net/ethernet/broadcom/b44.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2272,7 +2272,7 @@ static int b44_register_phy_one(struct b44 *bp)
22722272
goto err_out_mdiobus;
22732273
}
22742274

2275-
if (!bp->mii_bus->phy_map[bp->phy_addr] &&
2275+
if (!mdiobus_is_registered_device(bp->mii_bus, bp->phy_addr) &&
22762276
(sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) {
22772277

22782278
dev_info(sdev->dev,

drivers/net/ethernet/broadcom/genet/bcmmii.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv)
573573
}
574574

575575
if (pd->phy_address >= 0 && pd->phy_address < PHY_MAX_ADDR)
576-
phydev = mdio->phy_map[pd->phy_address];
576+
phydev = mdiobus_get_phy(mdio, pd->phy_address);
577577
else
578578
phydev = phy_find_first(mdio);
579579

drivers/net/ethernet/broadcom/tg3.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,7 +1406,7 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
14061406
u32 val;
14071407
struct phy_device *phydev;
14081408

1409-
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
1409+
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
14101410
switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
14111411
case PHY_ID_BCM50610:
14121412
case PHY_ID_BCM50610M:
@@ -1554,7 +1554,7 @@ static int tg3_mdio_init(struct tg3 *tp)
15541554
return i;
15551555
}
15561556

1557-
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
1557+
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
15581558

15591559
if (!phydev || !phydev->drv) {
15601560
dev_warn(&tp->pdev->dev, "No PHY devices\n");
@@ -1964,7 +1964,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
19641964
u32 old_tx_mode = tp->tx_mode;
19651965

19661966
if (tg3_flag(tp, USE_PHYLIB))
1967-
autoneg = tp->mdio_bus->phy_map[tp->phy_addr]->autoneg;
1967+
autoneg = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr)->autoneg;
19681968
else
19691969
autoneg = tp->link_config.autoneg;
19701970

@@ -2000,7 +2000,7 @@ static void tg3_adjust_link(struct net_device *dev)
20002000
u8 oldflowctrl, linkmesg = 0;
20012001
u32 mac_mode, lcl_adv, rmt_adv;
20022002
struct tg3 *tp = netdev_priv(dev);
2003-
struct phy_device *phydev = tp->mdio_bus->phy_map[tp->phy_addr];
2003+
struct phy_device *phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
20042004

20052005
spin_lock_bh(&tp->lock);
20062006

@@ -2089,7 +2089,7 @@ static int tg3_phy_init(struct tg3 *tp)
20892089
/* Bring the PHY back to a known state. */
20902090
tg3_bmcr_reset(tp);
20912091

2092-
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
2092+
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
20932093

20942094
/* Attach the MAC to the PHY. */
20952095
phydev = phy_connect(tp->dev, phydev_name(phydev),
@@ -2116,7 +2116,7 @@ static int tg3_phy_init(struct tg3 *tp)
21162116
SUPPORTED_Asym_Pause);
21172117
break;
21182118
default:
2119-
phy_disconnect(tp->mdio_bus->phy_map[tp->phy_addr]);
2119+
phy_disconnect(mdiobus_get_phy(tp->mdio_bus, tp->phy_addr));
21202120
return -EINVAL;
21212121
}
21222122

@@ -2136,7 +2136,7 @@ static void tg3_phy_start(struct tg3 *tp)
21362136
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
21372137
return;
21382138

2139-
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
2139+
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
21402140

21412141
if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
21422142
tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER;
@@ -2156,13 +2156,13 @@ static void tg3_phy_stop(struct tg3 *tp)
21562156
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
21572157
return;
21582158

2159-
phy_stop(tp->mdio_bus->phy_map[tp->phy_addr]);
2159+
phy_stop(mdiobus_get_phy(tp->mdio_bus, tp->phy_addr));
21602160
}
21612161

21622162
static void tg3_phy_fini(struct tg3 *tp)
21632163
{
21642164
if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) {
2165-
phy_disconnect(tp->mdio_bus->phy_map[tp->phy_addr]);
2165+
phy_disconnect(mdiobus_get_phy(tp->mdio_bus, tp->phy_addr));
21662166
tp->phy_flags &= ~TG3_PHYFLG_IS_CONNECTED;
21672167
}
21682168
}
@@ -4046,7 +4046,7 @@ static int tg3_power_down_prepare(struct tg3 *tp)
40464046
struct phy_device *phydev;
40474047
u32 phyid, advertising;
40484048

4049-
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
4049+
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
40504050

40514051
tp->phy_flags |= TG3_PHYFLG_IS_LOW_POWER;
40524052

@@ -12074,7 +12074,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1207412074
struct phy_device *phydev;
1207512075
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
1207612076
return -EAGAIN;
12077-
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
12077+
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
1207812078
return phy_ethtool_gset(phydev, cmd);
1207912079
}
1208012080

@@ -12141,7 +12141,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1214112141
struct phy_device *phydev;
1214212142
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
1214312143
return -EAGAIN;
12144-
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
12144+
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
1214512145
return phy_ethtool_sset(phydev, cmd);
1214612146
}
1214712147

@@ -12296,7 +12296,7 @@ static int tg3_nway_reset(struct net_device *dev)
1229612296
if (tg3_flag(tp, USE_PHYLIB)) {
1229712297
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
1229812298
return -EAGAIN;
12299-
r = phy_start_aneg(tp->mdio_bus->phy_map[tp->phy_addr]);
12299+
r = phy_start_aneg(mdiobus_get_phy(tp->mdio_bus, tp->phy_addr));
1230012300
} else {
1230112301
u32 bmcr;
1230212302

@@ -12414,7 +12414,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
1241412414
u32 newadv;
1241512415
struct phy_device *phydev;
1241612416

12417-
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
12417+
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
1241812418

1241912419
if (!(phydev->supported & SUPPORTED_Pause) ||
1242012420
(!(phydev->supported & SUPPORTED_Asym_Pause) &&
@@ -13924,7 +13924,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1392413924
struct phy_device *phydev;
1392513925
if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
1392613926
return -EAGAIN;
13927-
phydev = tp->mdio_bus->phy_map[tp->phy_addr];
13927+
phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr);
1392813928
return phy_mii_ioctl(phydev, ifr, cmd);
1392913929
}
1393013930

drivers/net/ethernet/ethoc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ static int ethoc_mdio_probe(struct net_device *dev)
678678
int err;
679679

680680
if (priv->phy_id != -1)
681-
phy = priv->mdio->phy_map[priv->phy_id];
681+
phy = mdiobus_get_phy(priv->mdio, priv->phy_id);
682682
else
683683
phy = phy_find_first(priv->mdio);
684684

@@ -766,7 +766,7 @@ static int ethoc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
766766
if (mdio->phy_id >= PHY_MAX_ADDR)
767767
return -ERANGE;
768768

769-
phy = priv->mdio->phy_map[mdio->phy_id];
769+
phy = mdiobus_get_phy(priv->mdio, mdio->phy_id);
770770
if (!phy)
771771
return -ENODEV;
772772
} else {

drivers/net/ethernet/faraday/ftgmac100.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ static int ftgmac100_mii_probe(struct ftgmac100 *priv)
839839

840840
/* search for connect PHY device */
841841
for (i = 0; i < PHY_MAX_ADDR; i++) {
842-
struct phy_device *tmp = priv->mii_bus->phy_map[i];
842+
struct phy_device *tmp = mdiobus_get_phy(priv->mii_bus, i);
843843

844844
if (tmp) {
845845
phydev = tmp;

drivers/net/ethernet/freescale/fec_main.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include <linux/irq.h>
4949
#include <linux/clk.h>
5050
#include <linux/platform_device.h>
51+
#include <linux/mdio.h>
5152
#include <linux/phy.h>
5253
#include <linux/fec.h>
5354
#include <linux/of.h>
@@ -1926,11 +1927,7 @@ static int fec_enet_mii_probe(struct net_device *ndev)
19261927
} else {
19271928
/* check for attached phy */
19281929
for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) {
1929-
if ((fep->mii_bus->phy_mask & (1 << phy_id)))
1930-
continue;
1931-
if (fep->mii_bus->phy_map[phy_id] == NULL)
1932-
continue;
1933-
if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
1930+
if (!mdiobus_is_registered_device(fep->mii_bus, phy_id))
19341931
continue;
19351932
if (dev_id--)
19361933
continue;

drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ int sxgbe_mdio_register(struct net_device *ndev)
180180
}
181181

182182
for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
183-
struct phy_device *phy = mdio_bus->phy_map[phy_addr];
183+
struct phy_device *phy = mdiobus_get_phy(mdio_bus, phy_addr);
184184

185185
if (phy) {
186186
char irq_num[4];

drivers/net/ethernet/smsc/smsc9420.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,8 @@ static int smsc9420_mii_probe(struct net_device *dev)
11581158
BUG_ON(pd->phy_dev);
11591159

11601160
/* Device only supports internal PHY at address 1 */
1161-
if (!pd->mii_bus->phy_map[1]) {
1161+
phydev = mdiobus_get_phy(pd->mii_bus, 1);
1162+
if (!phydev) {
11621163
netdev_err(dev, "no PHY found at address 1\n");
11631164
return -ENODEV;
11641165
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ int stmmac_mdio_register(struct net_device *ndev)
252252

253253
found = 0;
254254
for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
255-
struct phy_device *phydev = new_bus->phy_map[addr];
255+
struct phy_device *phydev = mdiobus_get_phy(new_bus, addr);
256256
if (phydev) {
257257
int act = 0;
258258
char irq_num[4];

drivers/net/ethernet/ti/davinci_mdio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ static int davinci_mdio_probe(struct platform_device *pdev)
393393

394394
/* scan and dump the bus */
395395
for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
396-
phy = data->bus->phy_map[addr];
396+
phy = mdiobus_get_phy(data->bus, addr);
397397
if (phy) {
398398
dev_info(dev, "phy[%d]: device %s, driver %s\n",
399399
phy->mdio.addr, phydev_name(phy),

drivers/net/phy/mdio_bus.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,48 @@
3838

3939
#include <asm/irq.h>
4040

41+
int mdiobus_register_device(struct mdio_device *mdiodev)
42+
{
43+
if (mdiodev->bus->mdio_map[mdiodev->addr])
44+
return -EBUSY;
45+
46+
mdiodev->bus->mdio_map[mdiodev->addr] = mdiodev;
47+
48+
return 0;
49+
}
50+
EXPORT_SYMBOL(mdiobus_register_device);
51+
52+
int mdiobus_unregister_device(struct mdio_device *mdiodev)
53+
{
54+
if (mdiodev->bus->mdio_map[mdiodev->addr] != mdiodev)
55+
return -EINVAL;
56+
57+
mdiodev->bus->mdio_map[mdiodev->addr] = NULL;
58+
59+
return 0;
60+
}
61+
EXPORT_SYMBOL(mdiobus_unregister_device);
62+
63+
struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr)
64+
{
65+
struct mdio_device *mdiodev = bus->mdio_map[addr];
66+
67+
if (!mdiodev)
68+
return NULL;
69+
70+
if (!(mdiodev->flags & MDIO_DEVICE_FLAG_PHY))
71+
return NULL;
72+
73+
return container_of(mdiodev, struct phy_device, mdio);
74+
}
75+
EXPORT_SYMBOL(mdiobus_get_phy);
76+
77+
bool mdiobus_is_registered_device(struct mii_bus *bus, int addr)
78+
{
79+
return bus->mdio_map[addr];
80+
}
81+
EXPORT_SYMBOL(mdiobus_is_registered_device);
82+
4183
/**
4284
* mdiobus_alloc_size - allocate a mii_bus structure
4385
* @size: extra amount of memory to allocate for private storage.
@@ -299,7 +341,7 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
299341

300342
error:
301343
while (--i >= 0) {
302-
struct phy_device *phydev = bus->phy_map[i];
344+
struct phy_device *phydev = mdiobus_get_phy(bus, i);
303345
if (phydev) {
304346
phy_device_remove(phydev);
305347
phy_device_free(phydev);
@@ -318,7 +360,7 @@ void mdiobus_unregister(struct mii_bus *bus)
318360
bus->state = MDIOBUS_UNREGISTERED;
319361

320362
for (i = 0; i < PHY_MAX_ADDR; i++) {
321-
struct phy_device *phydev = bus->phy_map[i];
363+
struct phy_device *phydev = mdiobus_get_phy(bus, i);
322364
if (phydev) {
323365
phy_device_remove(phydev);
324366
phy_device_free(phydev);

drivers/net/phy/phy_device.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
166166
mdiodev->dev.bus = &mdio_bus_type;
167167
mdiodev->bus = bus;
168168
mdiodev->addr = addr;
169+
mdiodev->flags = MDIO_DEVICE_FLAG_PHY;
169170

170171
dev->speed = 0;
171172
dev->duplex = -1;
@@ -383,10 +384,9 @@ int phy_device_register(struct phy_device *phydev)
383384
{
384385
int err;
385386

386-
/* Don't register a phy if one is already registered at this address */
387-
if (phydev->mdio.bus->phy_map[phydev->mdio.addr])
388-
return -EINVAL;
389-
phydev->mdio.bus->phy_map[phydev->mdio.addr] = phydev;
387+
err = mdiobus_register_device(&phydev->mdio);
388+
if (err)
389+
return err;
390390

391391
/* Run all of the fixups for this PHY */
392392
err = phy_scan_fixups(phydev);
@@ -404,7 +404,7 @@ int phy_device_register(struct phy_device *phydev)
404404
return 0;
405405

406406
out:
407-
phydev->mdio.bus->phy_map[phydev->mdio.addr] = NULL;
407+
mdiobus_unregister_device(&phydev->mdio);
408408
return err;
409409
}
410410
EXPORT_SYMBOL(phy_device_register);
@@ -419,11 +419,8 @@ EXPORT_SYMBOL(phy_device_register);
419419
*/
420420
void phy_device_remove(struct phy_device *phydev)
421421
{
422-
struct mii_bus *bus = phydev->mdio.bus;
423-
int addr = phydev->mdio.addr;
424-
425422
device_del(&phydev->mdio.dev);
426-
bus->phy_map[addr] = NULL;
423+
mdiobus_unregister_device(&phydev->mdio);
427424
}
428425
EXPORT_SYMBOL(phy_device_remove);
429426

@@ -433,11 +430,13 @@ EXPORT_SYMBOL(phy_device_remove);
433430
*/
434431
struct phy_device *phy_find_first(struct mii_bus *bus)
435432
{
433+
struct phy_device *phydev;
436434
int addr;
437435

438436
for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
439-
if (bus->phy_map[addr])
440-
return bus->phy_map[addr];
437+
phydev = mdiobus_get_phy(bus, addr);
438+
if (phydev)
439+
return phydev;
441440
}
442441
return NULL;
443442
}

0 commit comments

Comments
 (0)