kernel: bump 5.15 to 5.15.140
[openwrt/openwrt.git] / target / linux / generic / hack-5.15 / 795-backport-phylink_pcs-helpers.patch
1 From 027586ae8ecacff49757ed854c020f35d24a599c Mon Sep 17 00:00:00 2001
2 From: Daniel Golle <daniel@makrotopia.org>
3 Date: Sat, 11 Mar 2023 03:44:41 +0000
4 Subject: [PATCH] generic: backport some phylink helper functions
5
6 It isn't feasible to literally backport all upstream phylink_pcs changes
7 down to Linux 5.15: It's just too many patches, and many downstream
8 drivers and hacks are likely to break. We are too close to branching off
9 to risk this, and it's also just too much work.
10 Instead just add helper functions used by modern PCS drivers while keeping
11 the original functions instact as well. While this may add a kilobyte or
12 two of extra kernel size, it has the advantage that we get the best of both
13 worlds: None of the existing codepaths are touched, but yet we have the
14 option to backport singular improvements to Ethernet drivers where needed.
15
16 Signed-off-by: Daniel Golle <daniel@makrotopia.org>
17
18 --- a/include/linux/phylink.h
19 +++ b/include/linux/phylink.h
20 @@ -600,10 +600,37 @@ int phylink_speed_up(struct phylink *pl)
21 #define phylink_test(bm, mode) __phylink_do_bit(test_bit, bm, mode)
22
23 void phylink_set_port_modes(unsigned long *bits);
24 +
25 +/**
26 + * phylink_get_link_timer_ns - return the PCS link timer value
27 + * @interface: link &typedef phy_interface_t mode
28 + *
29 + * Return the PCS link timer setting in nanoseconds for the PHY @interface
30 + * mode, or -EINVAL if not appropriate.
31 + */
32 +static inline int phylink_get_link_timer_ns(phy_interface_t interface)
33 +{
34 + switch (interface) {
35 + case PHY_INTERFACE_MODE_SGMII:
36 + return 1600000;
37 +
38 + case PHY_INTERFACE_MODE_1000BASEX:
39 + case PHY_INTERFACE_MODE_2500BASEX:
40 + return 10000000;
41 +
42 + default:
43 + return -EINVAL;
44 + }
45 +}
46 +
47 void phylink_helper_basex_speed(struct phylink_link_state *state);
48
49 +void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
50 + u16 bmsr, u16 lpa);
51 void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs,
52 struct phylink_link_state *state);
53 +int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface,
54 + const unsigned long *advertising);
55 int phylink_mii_c22_pcs_set_advertisement(struct mdio_device *pcs,
56 phy_interface_t interface,
57 const unsigned long *advertising);
58 --- a/drivers/net/phy/phylink.c
59 +++ b/drivers/net/phy/phylink.c
60 @@ -931,7 +931,6 @@ static int phylink_change_inband_advert(
61
62 return 0;
63 }
64 -
65 static void phylink_mac_pcs_get_state(struct phylink *pl,
66 struct phylink_link_state *state)
67 {
68 @@ -3015,6 +3014,52 @@ void phylink_mii_c22_pcs_get_state(struc
69 EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_get_state);
70
71 /**
72 + * phylink_mii_c22_pcs_decode_state() - Decode MAC PCS state from MII registers
73 + * @state: a pointer to a &struct phylink_link_state.
74 + * @bmsr: The value of the %MII_BMSR register
75 + * @lpa: The value of the %MII_LPA register
76 + *
77 + * Helper for MAC PCS supporting the 802.3 clause 22 register set for
78 + * clause 37 negotiation and/or SGMII control.
79 + *
80 + * Parse the Clause 37 or Cisco SGMII link partner negotiation word into
81 + * the phylink @state structure. This is suitable to be used for implementing
82 + * the mac_pcs_get_state() member of the struct phylink_mac_ops structure if
83 + * accessing @bmsr and @lpa cannot be done with MDIO directly.
84 + */
85 +void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
86 + u16 bmsr, u16 lpa)
87 +{
88 + state->link = !!(bmsr & BMSR_LSTATUS);
89 + state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
90 + /* If there is no link or autonegotiation is disabled, the LP advertisement
91 + * data is not meaningful, so don't go any further.
92 + */
93 + if (!state->link || !state->an_enabled)
94 + return;
95 +
96 + switch (state->interface) {
97 + case PHY_INTERFACE_MODE_1000BASEX:
98 + phylink_decode_c37_word(state, lpa, SPEED_1000);
99 + break;
100 +
101 + case PHY_INTERFACE_MODE_2500BASEX:
102 + phylink_decode_c37_word(state, lpa, SPEED_2500);
103 + break;
104 +
105 + case PHY_INTERFACE_MODE_SGMII:
106 + case PHY_INTERFACE_MODE_QSGMII:
107 + phylink_decode_sgmii_word(state, lpa);
108 + break;
109 +
110 + default:
111 + state->link = false;
112 + break;
113 + }
114 +}
115 +EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_decode_state);
116 +
117 +/**
118 * phylink_mii_c22_pcs_set_advertisement() - configure the clause 37 PCS
119 * advertisement
120 * @pcs: a pointer to a &struct mdio_device.
121 @@ -3086,6 +3131,46 @@ int phylink_mii_c22_pcs_set_advertisemen
122 EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_set_advertisement);
123
124 /**
125 + * phylink_mii_c22_pcs_encode_advertisement() - configure the clause 37 PCS
126 + * advertisement
127 + * @interface: the PHY interface mode being configured
128 + * @advertising: the ethtool advertisement mask
129 + *
130 + * Helper for MAC PCS supporting the 802.3 clause 22 register set for
131 + * clause 37 negotiation and/or SGMII control.
132 + *
133 + * Encode the clause 37 PCS advertisement as specified by @interface and
134 + * @advertising.
135 + *
136 + * Return: The new value for @adv, or ``-EINVAL`` if it should not be changed.
137 + */
138 +int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface,
139 + const unsigned long *advertising)
140 +{
141 + u16 adv;
142 +
143 + switch (interface) {
144 + case PHY_INTERFACE_MODE_1000BASEX:
145 + case PHY_INTERFACE_MODE_2500BASEX:
146 + adv = ADVERTISE_1000XFULL;
147 + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
148 + advertising))
149 + adv |= ADVERTISE_1000XPAUSE;
150 + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
151 + advertising))
152 + adv |= ADVERTISE_1000XPSE_ASYM;
153 + return adv;
154 + case PHY_INTERFACE_MODE_SGMII:
155 + case PHY_INTERFACE_MODE_QSGMII:
156 + return 0x0001;
157 + default:
158 + /* Nothing to do for other modes */
159 + return -EINVAL;
160 + }
161 +}
162 +EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_encode_advertisement);
163 +
164 +/**
165 * phylink_mii_c22_pcs_config() - configure clause 22 PCS
166 * @pcs: a pointer to a &struct mdio_device.
167 * @mode: link autonegotiation mode