net: phy: don't require PHY interface mode during PHY creation

Currently we require PHY interface mode to be known when
finding/creating the PHY - the functions
  * phy_connect_phy_id()
  * phy_device_create()
  * create_phy_by_mask()
  * search_for_existing_phy()
  * get_phy_device_by_mask()
  * phy_find_by_mask()
all require the interface parameter, but the only thing done with it is
that it is assigned to phydev->interface.

This makes it impossible to find a PHY device without overwriting the
set mode.

Since the interface mode is not used during .probe() and should be used
at first in .config(), drop the interface parameter from these
functions. Make the default value of phydev->interface (in
phy_device_create()) to be PHY_INTERFACE_MODE_NA. Move the interface
parameter to phy_connect_dev(), where it should be.

Change all occurrences treewide. In occurrences where we don't call
phy_connect_dev() for some reason (they only configure the PHY without
connecting it to an ethernet controller), set
  phydev->interface = value from phy_find_by_mask call.

Signed-off-by: Marek Behún <marek.behun@nic.cz>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
This commit is contained in:
Marek Behún 2022-04-07 00:33:08 +02:00 committed by Ramon Fried
parent b638814e91
commit e24b58f5ed
17 changed files with 75 additions and 94 deletions

View File

@ -396,7 +396,7 @@ static void mox_phy_leds_start_blinking(void)
return;
}
phydev = phy_find_by_mask(bus, BIT(1), PHY_INTERFACE_MODE_RGMII);
phydev = phy_find_by_mask(bus, BIT(1));
if (!phydev) {
printf("Cannot get ethernet PHY!\n");
return;

View File

@ -345,7 +345,7 @@ int board_eth_init(struct bd_info *bis)
if (!bus)
return -EINVAL;
/* scan phy 4,5,6,7 */
phydev = phy_find_by_mask(bus, (0xf << 4), PHY_INTERFACE_MODE_RGMII);
phydev = phy_find_by_mask(bus, (0xf << 4));
if (!phydev) {
ret = -EINVAL;
goto free_bus;

View File

@ -194,11 +194,12 @@ void init_host_phys(struct mii_dev *bus)
for (k = 0; k < 2; ++k) {
struct phy_device *phydev;
phydev = phy_find_by_mask(bus, 1 << k,
PHY_INTERFACE_MODE_SGMII);
phydev = phy_find_by_mask(bus, 1 << k);
if (phydev)
if (phydev) {
phydev->interface = PHY_INTERFACE_MODE_SGMII;
phy_config(phydev);
}
}
}

View File

@ -28,6 +28,7 @@ static void ihs_phy_config(struct phy_device *phydev, bool qinpn, bool qoutpn)
{
u16 reg;
phydev->interface = PHY_INTERFACE_MODE_MII;
phy_config(phydev);
/* enable QSGMII autonegotiation with flow control */
@ -142,10 +143,9 @@ struct porttype *get_porttype(uint octo_phy_mask, uint k)
int init_single_phy(struct porttype *porttype, struct mii_dev *bus,
uint bus_idx, uint m, uint phy_idx)
{
struct phy_device *phydev = phy_find_by_mask(
bus, 1 << (m * 8 + phy_idx),
PHY_INTERFACE_MODE_MII);
struct phy_device *phydev;
phydev = phy_find_by_mask(bus, BIT(m * 8 + phy_idx));
printf(" %u", bus_idx * 32 + m * 8 + phy_idx);
if (!phydev)

View File

@ -435,11 +435,11 @@ static int tse_phy_init(struct altera_tse_priv *priv, void *dev)
if (priv->phyaddr)
mask = 1 << priv->phyaddr;
phydev = phy_find_by_mask(priv->bus, mask, priv->interface);
phydev = phy_find_by_mask(priv->bus, mask);
if (!phydev)
return -ENODEV;
phy_connect_dev(phydev, dev);
phy_connect_dev(phydev, dev, priv->interface);
phydev->supported &= PHY_GBIT_FEATURES;
phydev->advertising = phydev->supported;

View File

@ -614,11 +614,11 @@ static int ethoc_phy_init(struct ethoc *priv, void *dev)
mask = 1 << CONFIG_PHY_ADDR;
#endif
phydev = phy_find_by_mask(priv->bus, mask, PHY_INTERFACE_MODE_MII);
phydev = phy_find_by_mask(priv->bus, mask);
if (!phydev)
return -ENODEV;
phy_connect_dev(phydev, dev);
phy_connect_dev(phydev, dev, PHY_INTERFACE_MODE_MII);
phydev->supported &= PHY_BASIC_FEATURES;
phydev->advertising = phydev->supported;

View File

@ -416,13 +416,13 @@ static int pch_gbe_phy_init(struct udevice *dev)
struct phy_device *phydev;
int mask = 0xffffffff;
phydev = phy_find_by_mask(priv->bus, mask, plat->phy_interface);
phydev = phy_find_by_mask(priv->bus, mask);
if (!phydev) {
printf("pch_gbe: cannot find the phy\n");
return -1;
}
phy_connect_dev(phydev, dev);
phy_connect_dev(phydev, dev, plat->phy_interface);
phydev->supported &= PHY_GBIT_FEATURES;
phydev->advertising = phydev->supported;

View File

@ -11,8 +11,7 @@
#include <linux/delay.h>
#include <asm/gpio.h>
struct phy_device *phy_connect_phy_id(struct mii_dev *bus, struct udevice *dev,
phy_interface_t interface)
struct phy_device *phy_connect_phy_id(struct mii_dev *bus, struct udevice *dev)
{
struct phy_device *phydev;
struct ofnode_phandle_args phandle_args;
@ -61,7 +60,7 @@ struct phy_device *phy_connect_phy_id(struct mii_dev *bus, struct udevice *dev,
}
id = vendor << 16 | device;
phydev = phy_device_create(bus, 0, id, false, interface);
phydev = phy_device_create(bus, 0, id, false);
if (phydev)
phydev->node = node;

View File

@ -642,8 +642,7 @@ static struct phy_driver *generic_for_phy(struct phy_device *phydev)
return &genphy_driver;
}
static struct phy_driver *get_phy_driver(struct phy_device *phydev,
phy_interface_t interface)
static struct phy_driver *get_phy_driver(struct phy_device *phydev)
{
struct list_head *entry;
int phy_id = phydev->phy_id;
@ -660,8 +659,7 @@ static struct phy_driver *get_phy_driver(struct phy_device *phydev,
}
struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
u32 phy_id, bool is_c45,
phy_interface_t interface)
u32 phy_id, bool is_c45)
{
struct phy_device *dev;
@ -680,7 +678,7 @@ struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
dev->duplex = -1;
dev->link = 0;
dev->interface = interface;
dev->interface = PHY_INTERFACE_MODE_NA;
#ifdef CONFIG_DM_ETH
dev->node = ofnode_null();
@ -693,7 +691,7 @@ struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
dev->is_c45 = is_c45;
dev->bus = bus;
dev->drv = get_phy_driver(dev, interface);
dev->drv = get_phy_driver(dev);
if (phy_probe(dev)) {
printf("%s, PHY probe failed\n", __func__);
@ -742,8 +740,7 @@ int __weak get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
}
static struct phy_device *create_phy_by_mask(struct mii_dev *bus,
uint phy_mask, int devad,
phy_interface_t interface)
uint phy_mask, int devad)
{
u32 phy_id = 0xffffffff;
bool is_c45;
@ -764,8 +761,7 @@ static struct phy_device *create_phy_by_mask(struct mii_dev *bus,
/* If the PHY ID is mostly f's, we didn't find anything */
if (r == 0 && (phy_id & 0x1fffffff) != 0x1fffffff) {
is_c45 = (devad == MDIO_DEVAD_NONE) ? false : true;
return phy_device_create(bus, addr, phy_id, is_c45,
interface);
return phy_device_create(bus, addr, phy_id, is_c45);
}
next:
phy_mask &= ~(1 << addr);
@ -774,25 +770,22 @@ next:
}
static struct phy_device *search_for_existing_phy(struct mii_dev *bus,
uint phy_mask,
phy_interface_t interface)
uint phy_mask)
{
/* If we have one, return the existing device, with new interface */
while (phy_mask) {
int addr = ffs(phy_mask) - 1;
if (bus->phymap[addr]) {
bus->phymap[addr]->interface = interface;
if (bus->phymap[addr])
return bus->phymap[addr];
}
phy_mask &= ~(1 << addr);
}
return NULL;
}
static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
uint phy_mask,
phy_interface_t interface)
uint phy_mask)
{
struct phy_device *phydev;
int devad[] = {
@ -808,13 +801,12 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
int i, devad_cnt;
devad_cnt = sizeof(devad)/sizeof(int);
phydev = search_for_existing_phy(bus, phy_mask, interface);
phydev = search_for_existing_phy(bus, phy_mask);
if (phydev)
return phydev;
/* try different access clauses */
for (i = 0; i < devad_cnt; i++) {
phydev = create_phy_by_mask(bus, phy_mask,
devad[i], interface);
phydev = create_phy_by_mask(bus, phy_mask, devad[i]);
if (IS_ERR(phydev))
return NULL;
if (phydev)
@ -842,10 +834,9 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
* Description: Reads the ID registers of the PHY at @addr on the
* @bus, then allocates and returns the phy_device to represent it.
*/
static struct phy_device *get_phy_device(struct mii_dev *bus, int addr,
phy_interface_t interface)
static struct phy_device *get_phy_device(struct mii_dev *bus, int addr)
{
return get_phy_device_by_mask(bus, 1 << addr, interface);
return get_phy_device_by_mask(bus, 1 << addr);
}
int phy_reset(struct phy_device *phydev)
@ -904,18 +895,12 @@ int miiphy_reset(const char *devname, unsigned char addr)
struct mii_dev *bus = miiphy_get_dev_by_name(devname);
struct phy_device *phydev;
/*
* miiphy_reset was only used on standard PHYs, so we'll fake it here.
* If later code tries to connect with the right interface, this will
* be corrected by get_phy_device in phy_connect()
*/
phydev = get_phy_device(bus, addr, PHY_INTERFACE_MODE_MII);
phydev = get_phy_device(bus, addr);
return phy_reset(phydev);
}
struct phy_device *phy_find_by_mask(struct mii_dev *bus, uint phy_mask,
phy_interface_t interface)
struct phy_device *phy_find_by_mask(struct mii_dev *bus, uint phy_mask)
{
/* Reset the bus */
if (bus->reset) {
@ -925,13 +910,15 @@ struct phy_device *phy_find_by_mask(struct mii_dev *bus, uint phy_mask,
mdelay(15);
}
return get_phy_device_by_mask(bus, phy_mask, interface);
return get_phy_device_by_mask(bus, phy_mask);
}
#ifdef CONFIG_DM_ETH
void phy_connect_dev(struct phy_device *phydev, struct udevice *dev)
void phy_connect_dev(struct phy_device *phydev, struct udevice *dev,
phy_interface_t interface)
#else
void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev)
void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev,
phy_interface_t interface)
#endif
{
/* Soft Reset the PHY */
@ -942,13 +929,14 @@ void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev)
phydev->dev->name, dev->name);
}
phydev->dev = dev;
debug("%s connected to %s\n", dev->name, phydev->drv->name);
phydev->interface = interface;
debug("%s connected to %s mode %s\n", dev->name, phydev->drv->name,
phy_string_for_interface(interface));
}
#ifdef CONFIG_PHY_XILINX_GMII2RGMII
static struct phy_device *phy_connect_gmii2rgmii(struct mii_dev *bus,
struct udevice *dev,
phy_interface_t interface)
struct udevice *dev)
{
struct phy_device *phydev = NULL;
ofnode node;
@ -957,8 +945,7 @@ static struct phy_device *phy_connect_gmii2rgmii(struct mii_dev *bus,
node = ofnode_by_compatible(node, "xlnx,gmii-to-rgmii-1.0");
if (ofnode_valid(node)) {
phydev = phy_device_create(bus, 0,
PHY_GMII2RGMII_ID, false,
interface);
PHY_GMII2RGMII_ID, false);
if (phydev)
phydev->node = node;
break;
@ -990,24 +977,23 @@ struct phy_device *fixed_phy_create(ofnode node)
return NULL;
}
phydev = phy_device_create(NULL, 0, PHY_FIXED_ID, false,
ofnode_read_phy_mode(node));
phydev = phy_device_create(NULL, 0, PHY_FIXED_ID, false);
if (phydev)
phydev->node = subnode;
phydev->interface = ofnode_read_phy_mode(node);
return phydev;
}
static struct phy_device *phy_connect_fixed(struct mii_dev *bus,
struct udevice *dev,
phy_interface_t interface)
struct udevice *dev)
{
ofnode node = dev_ofnode(dev), subnode;
struct phy_device *phydev = NULL;
if (ofnode_phy_is_fixed_link(node, &subnode)) {
phydev = phy_device_create(bus, 0, PHY_FIXED_ID,
false, interface);
phydev = phy_device_create(bus, 0, PHY_FIXED_ID, false);
if (phydev)
phydev->node = subnode;
}
@ -1030,29 +1016,29 @@ struct phy_device *phy_connect(struct mii_dev *bus, int addr,
uint mask = (addr >= 0) ? (1 << addr) : 0xffffffff;
#ifdef CONFIG_PHY_FIXED
phydev = phy_connect_fixed(bus, dev, interface);
phydev = phy_connect_fixed(bus, dev);
#endif
#ifdef CONFIG_PHY_NCSI
if (!phydev)
phydev = phy_device_create(bus, 0, PHY_NCSI_ID, false, interface);
phydev = phy_device_create(bus, 0, PHY_NCSI_ID, false);
#endif
#ifdef CONFIG_PHY_ETHERNET_ID
if (!phydev)
phydev = phy_connect_phy_id(bus, dev, interface);
phydev = phy_connect_phy_id(bus, dev);
#endif
#ifdef CONFIG_PHY_XILINX_GMII2RGMII
if (!phydev)
phydev = phy_connect_gmii2rgmii(bus, dev, interface);
phydev = phy_connect_gmii2rgmii(bus, dev);
#endif
if (!phydev)
phydev = phy_find_by_mask(bus, mask, interface);
phydev = phy_find_by_mask(bus, mask);
if (phydev)
phy_connect_dev(phydev, dev);
phy_connect_dev(phydev, dev, interface);
else
printf("Could not get PHY for %s: addr %d\n", bus->name, addr);
return phydev;

View File

@ -42,13 +42,13 @@ static int xilinxgmiitorgmii_config(struct phy_device *phydev)
ext_phyaddr = ofnode_read_u32_default(phandle.node, "reg", -1);
ext_phydev = phy_find_by_mask(phydev->bus,
1 << ext_phyaddr,
PHY_INTERFACE_MODE_RGMII);
1 << ext_phyaddr);
if (!ext_phydev) {
printf("%s, No external phy device found\n", __func__);
return -EINVAL;
}
ext_phydev->interface = PHY_INTERFACE_MODE_RGMII;
ext_phydev->node = phandle.node;
phydev->priv = ext_phydev;

View File

@ -319,11 +319,11 @@ static int ravb_phy_config(struct udevice *dev)
mdelay(1);
}
phydev = phy_find_by_mask(eth->bus, mask, pdata->phy_interface);
phydev = phy_find_by_mask(eth->bus, mask);
if (!phydev)
return -ENODEV;
phy_connect_dev(phydev, dev);
phy_connect_dev(phydev, dev, pdata->phy_interface);
eth->phydev = phydev;

View File

@ -762,11 +762,11 @@ static int sh_eth_phy_config(struct udevice *dev)
struct phy_device *phydev;
int mask = 0xffffffff;
phydev = phy_find_by_mask(priv->bus, mask, pdata->phy_interface);
phydev = phy_find_by_mask(priv->bus, mask);
if (!phydev)
return -ENODEV;
phy_connect_dev(phydev, dev);
phy_connect_dev(phydev, dev, pdata->phy_interface);
port_info->phydev = phydev;
phy_config(phydev);

View File

@ -393,11 +393,11 @@ static int ave_phy_init(struct ave_private *priv, void *dev)
struct phy_device *phydev;
int mask = GENMASK(31, 0), ret;
phydev = phy_find_by_mask(priv->bus, mask, priv->phy_mode);
phydev = phy_find_by_mask(priv->bus, mask);
if (!phydev)
return -ENODEV;
phy_connect_dev(phydev, dev);
phy_connect_dev(phydev, dev, priv->phy_mode);
phydev->supported &= PHY_GBIT_FEATURES;
if (priv->max_speed) {

View File

@ -272,12 +272,11 @@ static int sunxi_emac_init_phy(struct emac_eth_dev *priv, void *dev)
if (ret)
return ret;
priv->phydev = phy_find_by_mask(priv->bus, mask,
PHY_INTERFACE_MODE_MII);
priv->phydev = phy_find_by_mask(priv->bus, mask);
if (!priv->phydev)
return -ENODEV;
phy_connect_dev(priv->phydev, dev);
phy_connect_dev(priv->phydev, dev, PHY_INTERFACE_MODE_MII);
phy_config(priv->phydev);
return 0;

View File

@ -77,8 +77,7 @@
EXPORT_FUNC(mdio_get_current_dev, struct mii_dev *,
mdio_get_current_dev, void)
EXPORT_FUNC(phy_find_by_mask, struct phy_device *, phy_find_by_mask,
struct mii_dev *bus, unsigned phy_mask,
phy_interface_t interface)
struct mii_dev *bus, unsigned phy_mask)
EXPORT_FUNC(mdio_phydev_for_ethname, struct phy_device *,
mdio_phydev_for_ethname, const char *ethname)
EXPORT_FUNC(miiphy_set_current_dev, int, miiphy_set_current_dev,

View File

@ -55,8 +55,7 @@ int i2c_read (uchar, uint, int , uchar* , int);
#endif
#ifdef CONFIG_PHY_AQUANTIA
struct mii_dev *mdio_get_current_dev(void);
struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
phy_interface_t interface);
struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask);
struct phy_device *mdio_phydev_for_ethname(const char *ethname);
int miiphy_set_current_dev(const char *devname);
#endif

View File

@ -388,11 +388,9 @@ int phy_reset(struct phy_device *phydev);
*
* @bus: MII/MDIO bus to scan
* @phy_mask: bitmap of PYH addresses to scan
* @interface: type of MAC-PHY interface
* @return: pointer to phy_device if a PHY is found, or NULL otherwise
*/
struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
phy_interface_t interface);
struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask);
#ifdef CONFIG_PHY_FIXED
@ -421,8 +419,10 @@ static inline struct phy_device *fixed_phy_create(ofnode node)
* phy_connect_dev() - Associates the given pair of PHY and Ethernet devices
* @phydev: PHY device
* @dev: Ethernet device
* @interface: type of MAC-PHY interface
*/
void phy_connect_dev(struct phy_device *phydev, struct udevice *dev);
void phy_connect_dev(struct phy_device *phydev, struct udevice *dev,
phy_interface_t interface);
/**
* phy_connect() - Creates a PHY device for the Ethernet interface
@ -449,12 +449,10 @@ struct phy_device *phy_connect(struct mii_dev *bus, int addr,
* @addr: PHY address on MDIO bus
* @phy_id: where to store the ID retrieved
* @is_c45: Device Identifiers if is_c45
* @interface: interface between the MAC and PHY
* @return: pointer to phy_device if a PHY is found, or NULL otherwise
*/
struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
u32 phy_id, bool is_c45,
phy_interface_t interface);
u32 phy_id, bool is_c45);
/**
* phy_connect_phy_id() - Connect to phy device by reading PHY id
@ -462,12 +460,10 @@ struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
*
* @bus: MII/MDIO bus that hosts the PHY
* @dev: Ethernet device to associate to the PHY
* @interface: Interface between the MAC and PHY
* @return: pointer to phy_device if a PHY is found,
* or NULL otherwise
*/
struct phy_device *phy_connect_phy_id(struct mii_dev *bus, struct udevice *dev,
phy_interface_t interface);
struct phy_device *phy_connect_phy_id(struct mii_dev *bus, struct udevice *dev);
static inline ofnode phy_get_ofnode(struct phy_device *phydev)
{
@ -482,8 +478,10 @@ static inline ofnode phy_get_ofnode(struct phy_device *phydev)
* phy_connect_dev() - Associates the given pair of PHY and Ethernet devices
* @phydev: PHY device
* @dev: Ethernet device
* @interface: type of MAC-PHY interface
*/
void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev);
void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev,
phy_interface_t interface);
/**
* phy_connect() - Creates a PHY device for the Ethernet interface