 910bdda6af
			
		
	
	910bdda6af
	
	
	
		
			
			All patches automatically rebased. Build system: x86_64 Build-tested: bcm2711/RPi4B, mt7622/RT3200 Run-tested: bcm2711/RPi4B, mt7622/RT3200 Signed-off-by: John Audia <therealgraysky@proton.me>
		
			
				
	
	
		
			107 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 0d22d4b626a4eaa3196019092eb6c1919e9f8caa Mon Sep 17 00:00:00 2001
 | |
| From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
 | |
| Date: Wed, 15 Dec 2021 15:34:20 +0000
 | |
| Subject: [PATCH] net: phylink: add pcs_validate() method
 | |
| 
 | |
| Add a hook for PCS to validate the link parameters. This avoids MAC
 | |
| drivers having to have knowledge of their PCS in their validate()
 | |
| method, thereby allowing several MAC drivers to be simplfied.
 | |
| 
 | |
| Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
 | |
| Signed-off-by: David S. Miller <davem@davemloft.net>
 | |
| ---
 | |
|  drivers/net/phy/phylink.c | 31 +++++++++++++++++++++++++++++++
 | |
|  include/linux/phylink.h   | 20 ++++++++++++++++++++
 | |
|  2 files changed, 51 insertions(+)
 | |
| 
 | |
| --- a/drivers/net/phy/phylink.c
 | |
| +++ b/drivers/net/phy/phylink.c
 | |
| @@ -160,13 +160,44 @@ static int phylink_validate_mac_and_pcs(
 | |
|  					struct phylink_link_state *state)
 | |
|  {
 | |
|  	struct phylink_pcs *pcs;
 | |
| +	int ret;
 | |
|  
 | |
| +	/* Get the PCS for this interface mode */
 | |
|  	if (pl->mac_ops->mac_select_pcs) {
 | |
|  		pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
 | |
|  		if (IS_ERR(pcs))
 | |
|  			return PTR_ERR(pcs);
 | |
| +	} else {
 | |
| +		pcs = pl->pcs;
 | |
|  	}
 | |
|  
 | |
| +	if (pcs) {
 | |
| +		/* The PCS, if present, must be setup before phylink_create()
 | |
| +		 * has been called. If the ops is not initialised, print an
 | |
| +		 * error and backtrace rather than oopsing the kernel.
 | |
| +		 */
 | |
| +		if (!pcs->ops) {
 | |
| +			phylink_err(pl, "interface %s: uninitialised PCS\n",
 | |
| +				    phy_modes(state->interface));
 | |
| +			dump_stack();
 | |
| +			return -EINVAL;
 | |
| +		}
 | |
| +
 | |
| +		/* Validate the link parameters with the PCS */
 | |
| +		if (pcs->ops->pcs_validate) {
 | |
| +			ret = pcs->ops->pcs_validate(pcs, supported, state);
 | |
| +			if (ret < 0 || phylink_is_empty_linkmode(supported))
 | |
| +				return -EINVAL;
 | |
| +
 | |
| +			/* Ensure the advertising mask is a subset of the
 | |
| +			 * supported mask.
 | |
| +			 */
 | |
| +			linkmode_and(state->advertising, state->advertising,
 | |
| +				     supported);
 | |
| +		}
 | |
| +	}
 | |
| +
 | |
| +	/* Then validate the link parameters with the MAC */
 | |
|  	pl->mac_ops->validate(pl->config, supported, state);
 | |
|  
 | |
|  	return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
 | |
| --- a/include/linux/phylink.h
 | |
| +++ b/include/linux/phylink.h
 | |
| @@ -398,6 +398,7 @@ struct phylink_pcs {
 | |
|  
 | |
|  /**
 | |
|   * struct phylink_pcs_ops - MAC PCS operations structure.
 | |
| + * @pcs_validate: validate the link configuration.
 | |
|   * @pcs_get_state: read the current MAC PCS link state from the hardware.
 | |
|   * @pcs_config: configure the MAC PCS for the selected mode and state.
 | |
|   * @pcs_an_restart: restart 802.3z BaseX autonegotiation.
 | |
| @@ -405,6 +406,8 @@ struct phylink_pcs {
 | |
|   *               (where necessary).
 | |
|   */
 | |
|  struct phylink_pcs_ops {
 | |
| +	int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
 | |
| +			    const struct phylink_link_state *state);
 | |
|  	void (*pcs_get_state)(struct phylink_pcs *pcs,
 | |
|  			      struct phylink_link_state *state);
 | |
|  	int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode,
 | |
| @@ -418,6 +421,23 @@ struct phylink_pcs_ops {
 | |
|  
 | |
|  #if 0 /* For kernel-doc purposes only. */
 | |
|  /**
 | |
| + * pcs_validate() - validate the link configuration.
 | |
| + * @pcs: a pointer to a &struct phylink_pcs.
 | |
| + * @supported: ethtool bitmask for supported link modes.
 | |
| + * @state: a const pointer to a &struct phylink_link_state.
 | |
| + *
 | |
| + * Validate the interface mode, and advertising's autoneg bit, removing any
 | |
| + * media ethtool link modes that would not be supportable from the supported
 | |
| + * mask. Phylink will propagate the changes to the advertising mask. See the
 | |
| + * &struct phylink_mac_ops validate() method.
 | |
| + *
 | |
| + * Returns -EINVAL if the interface mode/autoneg mode is not supported.
 | |
| + * Returns non-zero positive if the link state can be supported.
 | |
| + */
 | |
| +int pcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
 | |
| +		 const struct phylink_link_state *state);
 | |
| +
 | |
| +/**
 | |
|   * pcs_get_state() - Read the current inband link state from the hardware
 | |
|   * @pcs: a pointer to a &struct phylink_pcs.
 | |
|   * @state: a pointer to a &struct phylink_link_state.
 |