mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02: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
					
				
					 2 changed files with 55 additions and 39 deletions
				
			
		| 
						 | 
					@ -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);
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							if (ret == -ENOENT)
 | 
				
			||||||
			return 0;
 | 
								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…
	
		Reference in a new issue