mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-11 08:18:47 +00:00
phylink: convert to fwnode
Convert phylink to fwnode, switching phylink_create() from taking a device_node to taking a fwnode_handle. This will allow other firmware systems to take advantage of sfp/phylink support. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c19bb00070
commit
8fa7b9b6af
@ -142,59 +142,64 @@ static int phylink_validate(struct phylink *pl, unsigned long *supported,
|
|||||||
return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
|
return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int phylink_parse_fixedlink(struct phylink *pl, struct device_node *np)
|
static int phylink_parse_fixedlink(struct phylink *pl,
|
||||||
|
struct fwnode_handle *fwnode)
|
||||||
{
|
{
|
||||||
struct device_node *fixed_node;
|
struct fwnode_handle *fixed_node;
|
||||||
const struct phy_setting *s;
|
const struct phy_setting *s;
|
||||||
struct gpio_desc *desc;
|
struct gpio_desc *desc;
|
||||||
const __be32 *fixed_prop;
|
|
||||||
u32 speed;
|
u32 speed;
|
||||||
int ret, len;
|
int ret;
|
||||||
|
|
||||||
fixed_node = of_get_child_by_name(np, "fixed-link");
|
fixed_node = fwnode_get_named_child_node(fwnode, "fixed-link");
|
||||||
if (fixed_node) {
|
if (fixed_node) {
|
||||||
ret = of_property_read_u32(fixed_node, "speed", &speed);
|
ret = fwnode_property_read_u32(fixed_node, "speed", &speed);
|
||||||
|
|
||||||
pl->link_config.speed = speed;
|
pl->link_config.speed = speed;
|
||||||
pl->link_config.duplex = DUPLEX_HALF;
|
pl->link_config.duplex = DUPLEX_HALF;
|
||||||
|
|
||||||
if (of_property_read_bool(fixed_node, "full-duplex"))
|
if (fwnode_property_read_bool(fixed_node, "full-duplex"))
|
||||||
pl->link_config.duplex = DUPLEX_FULL;
|
pl->link_config.duplex = DUPLEX_FULL;
|
||||||
|
|
||||||
/* We treat the "pause" and "asym-pause" terminology as
|
/* We treat the "pause" and "asym-pause" terminology as
|
||||||
* defining the link partner's ability. */
|
* defining the link partner's ability. */
|
||||||
if (of_property_read_bool(fixed_node, "pause"))
|
if (fwnode_property_read_bool(fixed_node, "pause"))
|
||||||
pl->link_config.pause |= MLO_PAUSE_SYM;
|
pl->link_config.pause |= MLO_PAUSE_SYM;
|
||||||
if (of_property_read_bool(fixed_node, "asym-pause"))
|
if (fwnode_property_read_bool(fixed_node, "asym-pause"))
|
||||||
pl->link_config.pause |= MLO_PAUSE_ASYM;
|
pl->link_config.pause |= MLO_PAUSE_ASYM;
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
desc = fwnode_get_named_gpiod(&fixed_node->fwnode,
|
desc = fwnode_get_named_gpiod(fixed_node, "link-gpios",
|
||||||
"link-gpios", 0,
|
0, GPIOD_IN, "?");
|
||||||
GPIOD_IN, "?");
|
|
||||||
|
|
||||||
if (!IS_ERR(desc))
|
if (!IS_ERR(desc))
|
||||||
pl->link_gpio = desc;
|
pl->link_gpio = desc;
|
||||||
else if (desc == ERR_PTR(-EPROBE_DEFER))
|
else if (desc == ERR_PTR(-EPROBE_DEFER))
|
||||||
ret = -EPROBE_DEFER;
|
ret = -EPROBE_DEFER;
|
||||||
}
|
}
|
||||||
of_node_put(fixed_node);
|
fwnode_handle_put(fixed_node);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
fixed_prop = of_get_property(np, "fixed-link", &len);
|
u32 prop[5];
|
||||||
if (!fixed_prop) {
|
|
||||||
|
ret = fwnode_property_read_u32_array(fwnode, "fixed-link",
|
||||||
|
NULL, 0);
|
||||||
|
if (ret != ARRAY_SIZE(prop)) {
|
||||||
netdev_err(pl->netdev, "broken fixed-link?\n");
|
netdev_err(pl->netdev, "broken fixed-link?\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (len == 5 * sizeof(*fixed_prop)) {
|
|
||||||
pl->link_config.duplex = be32_to_cpu(fixed_prop[1]) ?
|
ret = fwnode_property_read_u32_array(fwnode, "fixed-link",
|
||||||
|
prop, ARRAY_SIZE(prop));
|
||||||
|
if (!ret) {
|
||||||
|
pl->link_config.duplex = prop[1] ?
|
||||||
DUPLEX_FULL : DUPLEX_HALF;
|
DUPLEX_FULL : DUPLEX_HALF;
|
||||||
pl->link_config.speed = be32_to_cpu(fixed_prop[2]);
|
pl->link_config.speed = prop[2];
|
||||||
if (be32_to_cpu(fixed_prop[3]))
|
if (prop[3])
|
||||||
pl->link_config.pause |= MLO_PAUSE_SYM;
|
pl->link_config.pause |= MLO_PAUSE_SYM;
|
||||||
if (be32_to_cpu(fixed_prop[4]))
|
if (prop[4])
|
||||||
pl->link_config.pause |= MLO_PAUSE_ASYM;
|
pl->link_config.pause |= MLO_PAUSE_ASYM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,17 +235,17 @@ static int phylink_parse_fixedlink(struct phylink *pl, struct device_node *np)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int phylink_parse_mode(struct phylink *pl, struct device_node *np)
|
static int phylink_parse_mode(struct phylink *pl, struct fwnode_handle *fwnode)
|
||||||
{
|
{
|
||||||
struct device_node *dn;
|
struct fwnode_handle *dn;
|
||||||
const char *managed;
|
const char *managed;
|
||||||
|
|
||||||
dn = of_get_child_by_name(np, "fixed-link");
|
dn = fwnode_get_named_child_node(fwnode, "fixed-link");
|
||||||
if (dn || of_find_property(np, "fixed-link", NULL))
|
if (dn || fwnode_property_present(fwnode, "fixed-link"))
|
||||||
pl->link_an_mode = MLO_AN_FIXED;
|
pl->link_an_mode = MLO_AN_FIXED;
|
||||||
of_node_put(dn);
|
fwnode_handle_put(dn);
|
||||||
|
|
||||||
if (of_property_read_string(np, "managed", &managed) == 0 &&
|
if (fwnode_property_read_string(fwnode, "managed", &managed) == 0 &&
|
||||||
strcmp(managed, "in-band-status") == 0) {
|
strcmp(managed, "in-band-status") == 0) {
|
||||||
if (pl->link_an_mode == MLO_AN_FIXED) {
|
if (pl->link_an_mode == MLO_AN_FIXED) {
|
||||||
netdev_err(pl->netdev,
|
netdev_err(pl->netdev,
|
||||||
@ -491,16 +496,24 @@ static void phylink_run_resolve(struct phylink *pl)
|
|||||||
|
|
||||||
static const struct sfp_upstream_ops sfp_phylink_ops;
|
static const struct sfp_upstream_ops sfp_phylink_ops;
|
||||||
|
|
||||||
static int phylink_register_sfp(struct phylink *pl, struct device_node *np)
|
static int phylink_register_sfp(struct phylink *pl,
|
||||||
|
struct fwnode_handle *fwnode)
|
||||||
{
|
{
|
||||||
struct device_node *sfp_np;
|
struct fwnode_reference_args ref;
|
||||||
|
int ret;
|
||||||
|
|
||||||
sfp_np = of_parse_phandle(np, "sfp", 0);
|
ret = fwnode_property_get_reference_args(fwnode, "sfp", NULL,
|
||||||
if (!sfp_np)
|
0, 0, &ref);
|
||||||
return 0;
|
if (ret < 0) {
|
||||||
|
if (ret == -ENOENT)
|
||||||
|
return 0;
|
||||||
|
|
||||||
pl->sfp_bus = sfp_register_upstream(of_fwnode_handle(sfp_np),
|
netdev_err(pl->netdev, "unable to parse \"sfp\" node: %d\n",
|
||||||
pl->netdev, pl,
|
ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
pl->sfp_bus = sfp_register_upstream(ref.fwnode, pl->netdev, pl,
|
||||||
&sfp_phylink_ops);
|
&sfp_phylink_ops);
|
||||||
if (!pl->sfp_bus)
|
if (!pl->sfp_bus)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -511,7 +524,8 @@ static int phylink_register_sfp(struct phylink *pl, struct device_node *np)
|
|||||||
/**
|
/**
|
||||||
* phylink_create() - create a phylink instance
|
* phylink_create() - create a phylink instance
|
||||||
* @ndev: a pointer to the &struct net_device
|
* @ndev: a pointer to the &struct net_device
|
||||||
* @np: a pointer to a &struct device_node describing the network interface
|
* @fwnode: a pointer to a &struct fwnode_handle describing the network
|
||||||
|
* interface
|
||||||
* @iface: the desired link mode defined by &typedef phy_interface_t
|
* @iface: the desired link mode defined by &typedef phy_interface_t
|
||||||
* @ops: a pointer to a &struct phylink_mac_ops for the MAC.
|
* @ops: a pointer to a &struct phylink_mac_ops for the MAC.
|
||||||
*
|
*
|
||||||
@ -521,7 +535,8 @@ static int phylink_register_sfp(struct phylink *pl, struct device_node *np)
|
|||||||
* Returns a pointer to a &struct phylink, or an error-pointer value. Users
|
* Returns a pointer to a &struct phylink, or an error-pointer value. Users
|
||||||
* must use IS_ERR() to check for errors from this function.
|
* must use IS_ERR() to check for errors from this function.
|
||||||
*/
|
*/
|
||||||
struct phylink *phylink_create(struct net_device *ndev, struct device_node *np,
|
struct phylink *phylink_create(struct net_device *ndev,
|
||||||
|
struct fwnode_handle *fwnode,
|
||||||
phy_interface_t iface,
|
phy_interface_t iface,
|
||||||
const struct phylink_mac_ops *ops)
|
const struct phylink_mac_ops *ops)
|
||||||
{
|
{
|
||||||
@ -549,21 +564,21 @@ struct phylink *phylink_create(struct net_device *ndev, struct device_node *np,
|
|||||||
linkmode_copy(pl->link_config.advertising, pl->supported);
|
linkmode_copy(pl->link_config.advertising, pl->supported);
|
||||||
phylink_validate(pl, pl->supported, &pl->link_config);
|
phylink_validate(pl, pl->supported, &pl->link_config);
|
||||||
|
|
||||||
ret = phylink_parse_mode(pl, np);
|
ret = phylink_parse_mode(pl, fwnode);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
kfree(pl);
|
kfree(pl);
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pl->link_an_mode == MLO_AN_FIXED) {
|
if (pl->link_an_mode == MLO_AN_FIXED) {
|
||||||
ret = phylink_parse_fixedlink(pl, np);
|
ret = phylink_parse_fixedlink(pl, fwnode);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
kfree(pl);
|
kfree(pl);
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = phylink_register_sfp(pl, np);
|
ret = phylink_register_sfp(pl, fwnode);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
kfree(pl);
|
kfree(pl);
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
struct device_node;
|
struct device_node;
|
||||||
struct ethtool_cmd;
|
struct ethtool_cmd;
|
||||||
|
struct fwnode_handle;
|
||||||
struct net_device;
|
struct net_device;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -182,7 +183,7 @@ void mac_link_up(struct net_device *ndev, unsigned int mode,
|
|||||||
struct phy_device *phy);
|
struct phy_device *phy);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct phylink *phylink_create(struct net_device *, struct device_node *,
|
struct phylink *phylink_create(struct net_device *, struct fwnode_handle *,
|
||||||
phy_interface_t iface, const struct phylink_mac_ops *ops);
|
phy_interface_t iface, const struct phylink_mac_ops *ops);
|
||||||
void phylink_destroy(struct phylink *);
|
void phylink_destroy(struct phylink *);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user