2019-06-01 11:08:42 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2010-10-27 02:07:13 +04:00
/*
* OF helpers for network devices .
*
* Initially copied out of arch / powerpc / kernel / prom_parse . c
*/
# include <linux/etherdevice.h>
# include <linux/kernel.h>
# include <linux/of_net.h>
2019-05-03 17:27:06 +03:00
# include <linux/of_platform.h>
2011-07-04 10:03:17 +04:00
# include <linux/phy.h>
2011-07-29 10:05:38 +04:00
# include <linux/export.h>
2019-05-03 17:27:06 +03:00
# include <linux/device.h>
2011-07-04 10:03:17 +04:00
/**
* of_get_phy_mode - Get phy mode for given device_node
* @ np : Pointer to the given device_node
net: of_get_phy_mode: Change API to solve int/unit warnings
Before this change of_get_phy_mode() returned an enum,
phy_interface_t. On error, -ENODEV etc, is returned. If the result of
the function is stored in a variable of type phy_interface_t, and the
compiler has decided to represent this as an unsigned int, comparision
with -ENODEV etc, is a signed vs unsigned comparision.
Fix this problem by changing the API. Make the function return an
error, or 0 on success, and pass a pointer, of type phy_interface_t,
where the phy mode should be stored.
v2:
Return with *interface set to PHY_INTERFACE_MODE_NA on error.
Add error checks to all users of of_get_phy_mode()
Fixup a few reverse christmas tree errors
Fixup a few slightly malformed reverse christmas trees
v3:
Fix 0-day reported errors.
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-04 04:40:33 +03:00
* @ interface : Pointer to the result
2011-07-04 10:03:17 +04:00
*
2013-11-15 10:23:32 +04:00
* The function gets phy interface string from property ' phy - mode ' or
net: of_get_phy_mode: Change API to solve int/unit warnings
Before this change of_get_phy_mode() returned an enum,
phy_interface_t. On error, -ENODEV etc, is returned. If the result of
the function is stored in a variable of type phy_interface_t, and the
compiler has decided to represent this as an unsigned int, comparision
with -ENODEV etc, is a signed vs unsigned comparision.
Fix this problem by changing the API. Make the function return an
error, or 0 on success, and pass a pointer, of type phy_interface_t,
where the phy mode should be stored.
v2:
Return with *interface set to PHY_INTERFACE_MODE_NA on error.
Add error checks to all users of of_get_phy_mode()
Fixup a few reverse christmas tree errors
Fixup a few slightly malformed reverse christmas trees
v3:
Fix 0-day reported errors.
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-04 04:40:33 +03:00
* ' phy - connection - type ' . The index in phy_modes table is set in
* interface and 0 returned . In case of error interface is set to
* PHY_INTERFACE_MODE_NA and an errno is returned , e . g . - ENODEV .
2011-07-04 10:03:17 +04:00
*/
net: of_get_phy_mode: Change API to solve int/unit warnings
Before this change of_get_phy_mode() returned an enum,
phy_interface_t. On error, -ENODEV etc, is returned. If the result of
the function is stored in a variable of type phy_interface_t, and the
compiler has decided to represent this as an unsigned int, comparision
with -ENODEV etc, is a signed vs unsigned comparision.
Fix this problem by changing the API. Make the function return an
error, or 0 on success, and pass a pointer, of type phy_interface_t,
where the phy mode should be stored.
v2:
Return with *interface set to PHY_INTERFACE_MODE_NA on error.
Add error checks to all users of of_get_phy_mode()
Fixup a few reverse christmas tree errors
Fixup a few slightly malformed reverse christmas trees
v3:
Fix 0-day reported errors.
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-04 04:40:33 +03:00
int of_get_phy_mode ( struct device_node * np , phy_interface_t * interface )
2011-07-04 10:03:17 +04:00
{
const char * pm ;
int err , i ;
net: of_get_phy_mode: Change API to solve int/unit warnings
Before this change of_get_phy_mode() returned an enum,
phy_interface_t. On error, -ENODEV etc, is returned. If the result of
the function is stored in a variable of type phy_interface_t, and the
compiler has decided to represent this as an unsigned int, comparision
with -ENODEV etc, is a signed vs unsigned comparision.
Fix this problem by changing the API. Make the function return an
error, or 0 on success, and pass a pointer, of type phy_interface_t,
where the phy mode should be stored.
v2:
Return with *interface set to PHY_INTERFACE_MODE_NA on error.
Add error checks to all users of of_get_phy_mode()
Fixup a few reverse christmas tree errors
Fixup a few slightly malformed reverse christmas trees
v3:
Fix 0-day reported errors.
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-04 04:40:33 +03:00
* interface = PHY_INTERFACE_MODE_NA ;
2011-07-04 10:03:17 +04:00
err = of_property_read_string ( np , " phy-mode " , & pm ) ;
2013-11-15 10:23:32 +04:00
if ( err < 0 )
err = of_property_read_string ( np , " phy-connection-type " , & pm ) ;
2011-07-04 10:03:17 +04:00
if ( err < 0 )
return err ;
2014-02-12 05:27:39 +04:00
for ( i = 0 ; i < PHY_INTERFACE_MODE_MAX ; i + + )
net: of_get_phy_mode: Change API to solve int/unit warnings
Before this change of_get_phy_mode() returned an enum,
phy_interface_t. On error, -ENODEV etc, is returned. If the result of
the function is stored in a variable of type phy_interface_t, and the
compiler has decided to represent this as an unsigned int, comparision
with -ENODEV etc, is a signed vs unsigned comparision.
Fix this problem by changing the API. Make the function return an
error, or 0 on success, and pass a pointer, of type phy_interface_t,
where the phy mode should be stored.
v2:
Return with *interface set to PHY_INTERFACE_MODE_NA on error.
Add error checks to all users of of_get_phy_mode()
Fixup a few reverse christmas tree errors
Fixup a few slightly malformed reverse christmas trees
v3:
Fix 0-day reported errors.
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-11-04 04:40:33 +03:00
if ( ! strcasecmp ( pm , phy_modes ( i ) ) ) {
* interface = i ;
return 0 ;
}
2011-07-04 10:03:17 +04:00
return - ENODEV ;
}
EXPORT_SYMBOL_GPL ( of_get_phy_mode ) ;
2010-10-27 02:07:13 +04:00
2015-03-18 22:25:46 +03:00
static const void * of_get_mac_addr ( struct device_node * np , const char * name )
{
struct property * pp = of_find_property ( np , name , NULL ) ;
if ( pp & & pp - > length = = ETH_ALEN & & is_valid_ether_addr ( pp - > value ) )
return pp - > value ;
return NULL ;
}
2019-05-03 17:27:06 +03:00
static const void * of_get_mac_addr_nvmem ( struct device_node * np )
{
int ret ;
2019-05-10 12:35:14 +03:00
const void * mac ;
u8 nvmem_mac [ ETH_ALEN ] ;
2019-05-03 17:27:06 +03:00
struct platform_device * pdev = of_find_device_by_node ( np ) ;
if ( ! pdev )
return ERR_PTR ( - ENODEV ) ;
2019-05-10 12:35:14 +03:00
ret = nvmem_get_mac_address ( & pdev - > dev , & nvmem_mac ) ;
2019-05-13 12:41:39 +03:00
if ( ret ) {
put_device ( & pdev - > dev ) ;
2019-05-03 17:27:06 +03:00
return ERR_PTR ( ret ) ;
2019-05-13 12:41:39 +03:00
}
2019-05-03 17:27:06 +03:00
2019-05-10 12:35:14 +03:00
mac = devm_kmemdup ( & pdev - > dev , nvmem_mac , ETH_ALEN , GFP_KERNEL ) ;
2019-05-13 12:41:39 +03:00
put_device ( & pdev - > dev ) ;
2019-05-10 12:35:14 +03:00
if ( ! mac )
2019-05-03 17:27:06 +03:00
return ERR_PTR ( - ENOMEM ) ;
2019-05-10 12:35:14 +03:00
return mac ;
2019-05-03 17:27:06 +03:00
}
2010-10-27 02:07:13 +04:00
/**
* Search the device tree for the best MAC address to use . ' mac - address ' is
* checked first , because that is supposed to contain to " most recent " MAC
* address . If that isn ' t set , then ' local - mac - address ' is checked next ,
2019-05-03 17:27:06 +03:00
* because that is the default address . If that isn ' t set , then the obsolete
* ' address ' is checked , just in case we ' re using an old device tree . If any
* of the above isn ' t set , then try to get MAC address from nvmem cell named
* ' mac - address ' .
2010-10-27 02:07:13 +04:00
*
* Note that the ' address ' property is supposed to contain a virtual address of
* the register set , but some DTS files have redefined that property to be the
* MAC address .
*
* All - zero MAC addresses are rejected , because those could be properties that
* exist in the device tree , but were not set by U - Boot . For example , the
* DTS could define ' mac - address ' and ' local - mac - address ' , with zero MAC
* addresses . Some older U - Boots only initialized ' local - mac - address ' . In
* this case , the real MAC is in ' local - mac - address ' , and ' mac - address ' exists
* but is all zeros .
2019-05-03 17:27:06 +03:00
*
* Return : Will be a valid pointer on success and ERR_PTR in case of error .
2010-10-27 02:07:13 +04:00
*/
const void * of_get_mac_address ( struct device_node * np )
{
2015-03-18 22:25:46 +03:00
const void * addr ;
2010-10-27 02:07:13 +04:00
2015-03-18 22:25:46 +03:00
addr = of_get_mac_addr ( np , " mac-address " ) ;
if ( addr )
return addr ;
2010-10-27 02:07:13 +04:00
2015-03-18 22:25:46 +03:00
addr = of_get_mac_addr ( np , " local-mac-address " ) ;
if ( addr )
return addr ;
2010-10-27 02:07:13 +04:00
2019-05-03 17:27:06 +03:00
addr = of_get_mac_addr ( np , " address " ) ;
if ( addr )
return addr ;
return of_get_mac_addr_nvmem ( np ) ;
2010-10-27 02:07:13 +04:00
}
EXPORT_SYMBOL ( of_get_mac_address ) ;