kernel: 5.15: update Aquantia PHY driver to v6.1 code
[openwrt/openwrt.git] / target / linux / generic / backport-5.15 / 703-11-v5.17-net-phylink-add-pcs_validate-method.patch
1 From 0d22d4b626a4eaa3196019092eb6c1919e9f8caa Mon Sep 17 00:00:00 2001
2 From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
3 Date: Wed, 15 Dec 2021 15:34:20 +0000
4 Subject: [PATCH] net: phylink: add pcs_validate() method
5
6 Add a hook for PCS to validate the link parameters. This avoids MAC
7 drivers having to have knowledge of their PCS in their validate()
8 method, thereby allowing several MAC drivers to be simplfied.
9
10 Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
11 Signed-off-by: David S. Miller <davem@davemloft.net>
12 ---
13 drivers/net/phy/phylink.c | 31 +++++++++++++++++++++++++++++++
14 include/linux/phylink.h | 20 ++++++++++++++++++++
15 2 files changed, 51 insertions(+)
16
17 --- a/drivers/net/phy/phylink.c
18 +++ b/drivers/net/phy/phylink.c
19 @@ -160,13 +160,44 @@ static int phylink_validate_mac_and_pcs(
20 struct phylink_link_state *state)
21 {
22 struct phylink_pcs *pcs;
23 + int ret;
24
25 + /* Get the PCS for this interface mode */
26 if (pl->mac_ops->mac_select_pcs) {
27 pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
28 if (IS_ERR(pcs))
29 return PTR_ERR(pcs);
30 + } else {
31 + pcs = pl->pcs;
32 }
33
34 + if (pcs) {
35 + /* The PCS, if present, must be setup before phylink_create()
36 + * has been called. If the ops is not initialised, print an
37 + * error and backtrace rather than oopsing the kernel.
38 + */
39 + if (!pcs->ops) {
40 + phylink_err(pl, "interface %s: uninitialised PCS\n",
41 + phy_modes(state->interface));
42 + dump_stack();
43 + return -EINVAL;
44 + }
45 +
46 + /* Validate the link parameters with the PCS */
47 + if (pcs->ops->pcs_validate) {
48 + ret = pcs->ops->pcs_validate(pcs, supported, state);
49 + if (ret < 0 || phylink_is_empty_linkmode(supported))
50 + return -EINVAL;
51 +
52 + /* Ensure the advertising mask is a subset of the
53 + * supported mask.
54 + */
55 + linkmode_and(state->advertising, state->advertising,
56 + supported);
57 + }
58 + }
59 +
60 + /* Then validate the link parameters with the MAC */
61 pl->mac_ops->validate(pl->config, supported, state);
62
63 return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
64 --- a/include/linux/phylink.h
65 +++ b/include/linux/phylink.h
66 @@ -398,6 +398,7 @@ struct phylink_pcs {
67
68 /**
69 * struct phylink_pcs_ops - MAC PCS operations structure.
70 + * @pcs_validate: validate the link configuration.
71 * @pcs_get_state: read the current MAC PCS link state from the hardware.
72 * @pcs_config: configure the MAC PCS for the selected mode and state.
73 * @pcs_an_restart: restart 802.3z BaseX autonegotiation.
74 @@ -405,6 +406,8 @@ struct phylink_pcs {
75 * (where necessary).
76 */
77 struct phylink_pcs_ops {
78 + int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
79 + const struct phylink_link_state *state);
80 void (*pcs_get_state)(struct phylink_pcs *pcs,
81 struct phylink_link_state *state);
82 int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode,
83 @@ -418,6 +421,23 @@ struct phylink_pcs_ops {
84
85 #if 0 /* For kernel-doc purposes only. */
86 /**
87 + * pcs_validate() - validate the link configuration.
88 + * @pcs: a pointer to a &struct phylink_pcs.
89 + * @supported: ethtool bitmask for supported link modes.
90 + * @state: a const pointer to a &struct phylink_link_state.
91 + *
92 + * Validate the interface mode, and advertising's autoneg bit, removing any
93 + * media ethtool link modes that would not be supportable from the supported
94 + * mask. Phylink will propagate the changes to the advertising mask. See the
95 + * &struct phylink_mac_ops validate() method.
96 + *
97 + * Returns -EINVAL if the interface mode/autoneg mode is not supported.
98 + * Returns non-zero positive if the link state can be supported.
99 + */
100 +int pcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
101 + const struct phylink_link_state *state);
102 +
103 +/**
104 * pcs_get_state() - Read the current inband link state from the hardware
105 * @pcs: a pointer to a &struct phylink_pcs.
106 * @state: a pointer to a &struct phylink_link_state.