generic: backport some phylink helper functions
[openwrt/openwrt.git] / target / linux / generic / hack-5.15 / 795-backport-phylink_pcs-helpers.patch
1 --- a/include/linux/phylink.h
2 +++ b/include/linux/phylink.h
3 @@ -584,10 +584,37 @@ int phylink_speed_up(struct phylink *pl)
4 #define phylink_test(bm, mode) __phylink_do_bit(test_bit, bm, mode)
5
6 void phylink_set_port_modes(unsigned long *bits);
7 +
8 +/**
9 + * phylink_get_link_timer_ns - return the PCS link timer value
10 + * @interface: link &typedef phy_interface_t mode
11 + *
12 + * Return the PCS link timer setting in nanoseconds for the PHY @interface
13 + * mode, or -EINVAL if not appropriate.
14 + */
15 +static inline int phylink_get_link_timer_ns(phy_interface_t interface)
16 +{
17 + switch (interface) {
18 + case PHY_INTERFACE_MODE_SGMII:
19 + return 1600000;
20 +
21 + case PHY_INTERFACE_MODE_1000BASEX:
22 + case PHY_INTERFACE_MODE_2500BASEX:
23 + return 10000000;
24 +
25 + default:
26 + return -EINVAL;
27 + }
28 +}
29 +
30 void phylink_helper_basex_speed(struct phylink_link_state *state);
31
32 +void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
33 + u16 bmsr, u16 lpa);
34 void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs,
35 struct phylink_link_state *state);
36 +int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface,
37 + const unsigned long *advertising);
38 int phylink_mii_c22_pcs_set_advertisement(struct mdio_device *pcs,
39 phy_interface_t interface,
40 const unsigned long *advertising);
41 --- a/drivers/net/phy/phylink.c
42 +++ b/drivers/net/phy/phylink.c
43 @@ -885,7 +885,6 @@ static int phylink_change_inband_advert(
44
45 return 0;
46 }
47 -
48 static void phylink_mac_pcs_get_state(struct phylink *pl,
49 struct phylink_link_state *state)
50 {
51 @@ -2966,6 +2965,52 @@ void phylink_mii_c22_pcs_get_state(struc
52 EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_get_state);
53
54 /**
55 + * phylink_mii_c22_pcs_decode_state() - Decode MAC PCS state from MII registers
56 + * @state: a pointer to a &struct phylink_link_state.
57 + * @bmsr: The value of the %MII_BMSR register
58 + * @lpa: The value of the %MII_LPA register
59 + *
60 + * Helper for MAC PCS supporting the 802.3 clause 22 register set for
61 + * clause 37 negotiation and/or SGMII control.
62 + *
63 + * Parse the Clause 37 or Cisco SGMII link partner negotiation word into
64 + * the phylink @state structure. This is suitable to be used for implementing
65 + * the mac_pcs_get_state() member of the struct phylink_mac_ops structure if
66 + * accessing @bmsr and @lpa cannot be done with MDIO directly.
67 + */
68 +void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
69 + u16 bmsr, u16 lpa)
70 +{
71 + state->link = !!(bmsr & BMSR_LSTATUS);
72 + state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
73 + /* If there is no link or autonegotiation is disabled, the LP advertisement
74 + * data is not meaningful, so don't go any further.
75 + */
76 + if (!state->link || !state->an_enabled)
77 + return;
78 +
79 + switch (state->interface) {
80 + case PHY_INTERFACE_MODE_1000BASEX:
81 + phylink_decode_c37_word(state, lpa, SPEED_1000);
82 + break;
83 +
84 + case PHY_INTERFACE_MODE_2500BASEX:
85 + phylink_decode_c37_word(state, lpa, SPEED_2500);
86 + break;
87 +
88 + case PHY_INTERFACE_MODE_SGMII:
89 + case PHY_INTERFACE_MODE_QSGMII:
90 + phylink_decode_sgmii_word(state, lpa);
91 + break;
92 +
93 + default:
94 + state->link = false;
95 + break;
96 + }
97 +}
98 +EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_decode_state);
99 +
100 +/**
101 * phylink_mii_c22_pcs_set_advertisement() - configure the clause 37 PCS
102 * advertisement
103 * @pcs: a pointer to a &struct mdio_device.
104 @@ -3037,6 +3082,46 @@ int phylink_mii_c22_pcs_set_advertisemen
105 EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_set_advertisement);
106
107 /**
108 + * phylink_mii_c22_pcs_encode_advertisement() - configure the clause 37 PCS
109 + * advertisement
110 + * @interface: the PHY interface mode being configured
111 + * @advertising: the ethtool advertisement mask
112 + *
113 + * Helper for MAC PCS supporting the 802.3 clause 22 register set for
114 + * clause 37 negotiation and/or SGMII control.
115 + *
116 + * Encode the clause 37 PCS advertisement as specified by @interface and
117 + * @advertising.
118 + *
119 + * Return: The new value for @adv, or ``-EINVAL`` if it should not be changed.
120 + */
121 +int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface,
122 + const unsigned long *advertising)
123 +{
124 + u16 adv;
125 +
126 + switch (interface) {
127 + case PHY_INTERFACE_MODE_1000BASEX:
128 + case PHY_INTERFACE_MODE_2500BASEX:
129 + adv = ADVERTISE_1000XFULL;
130 + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
131 + advertising))
132 + adv |= ADVERTISE_1000XPAUSE;
133 + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
134 + advertising))
135 + adv |= ADVERTISE_1000XPSE_ASYM;
136 + return adv;
137 + case PHY_INTERFACE_MODE_SGMII:
138 + case PHY_INTERFACE_MODE_QSGMII:
139 + return 0x0001;
140 + default:
141 + /* Nothing to do for other modes */
142 + return -EINVAL;
143 + }
144 +}
145 +EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_encode_advertisement);
146 +
147 +/**
148 * phylink_mii_c22_pcs_config() - configure clause 22 PCS
149 * @pcs: a pointer to a &struct mdio_device.
150 * @mode: link autonegotiation mode