developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 1 | From 318f81610f630a026fd5ca0d4da7e34df25df663 Mon Sep 17 00:00:00 2001 |
| 2 | From: Sam Shih <sam.shih@mediatek.com> |
| 3 | Date: Fri, 2 Jun 2023 13:06:02 +0800 |
| 4 | Subject: [PATCH] |
| 5 | [backport-networking-drivers][999-1711-net-phy-add-phylink-pcs-decode-helper.patch] |
| 6 | |
| 7 | --- |
| 8 | drivers/net/phy/Makefile | 3 +- |
| 9 | drivers/net/phy/linkmode.c | 95 +++++++++++++++++++ |
| 10 | drivers/net/phy/phylink.c | 188 +++++++++++++++++++++++++++++++++++++ |
| 11 | include/linux/linkmode.h | 6 ++ |
| 12 | include/linux/mii.h | 39 ++++++++ |
| 13 | include/linux/phylink.h | 30 ++++++ |
| 14 | include/uapi/linux/mdio.h | 26 +++++ |
| 15 | include/uapi/linux/mii.h | 17 ++++ |
| 16 | 8 files changed, 403 insertions(+), 1 deletion(-) |
| 17 | create mode 100644 drivers/net/phy/linkmode.c |
| 18 | |
developer | 38afb1a | 2023-04-17 09:57:27 +0800 | [diff] [blame] | 19 | diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 20 | index 8ea612a85..437ff2a2c 100644 |
developer | 38afb1a | 2023-04-17 09:57:27 +0800 | [diff] [blame] | 21 | --- a/drivers/net/phy/Makefile |
| 22 | +++ b/drivers/net/phy/Makefile |
| 23 | @@ -1,7 +1,8 @@ |
| 24 | # SPDX-License-Identifier: GPL-2.0 |
| 25 | # Makefile for Linux PHY drivers and MDIO bus drivers |
| 26 | |
| 27 | -libphy-y := phy.o phy-c45.o phy-core.o phy_device.o |
| 28 | +libphy-y := phy.o phy-c45.o phy-core.o phy_device.o \ |
| 29 | + linkmode.o |
| 30 | mdio-bus-y += mdio_bus.o mdio_device.o |
| 31 | |
| 32 | ifdef CONFIG_MDIO_DEVICE |
| 33 | diff --git a/drivers/net/phy/linkmode.c b/drivers/net/phy/linkmode.c |
| 34 | new file mode 100644 |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 35 | index 000000000..a5a347bca |
developer | 38afb1a | 2023-04-17 09:57:27 +0800 | [diff] [blame] | 36 | --- /dev/null |
| 37 | +++ b/drivers/net/phy/linkmode.c |
| 38 | @@ -0,0 +1,95 @@ |
| 39 | +// SPDX-License-Identifier: GPL-2.0+ |
| 40 | +#include <linux/linkmode.h> |
| 41 | + |
| 42 | +/** |
| 43 | + * linkmode_resolve_pause - resolve the allowable pause modes |
| 44 | + * @local_adv: local advertisement in ethtool format |
| 45 | + * @partner_adv: partner advertisement in ethtool format |
| 46 | + * @tx_pause: pointer to bool to indicate whether transmit pause should be |
| 47 | + * enabled. |
| 48 | + * @rx_pause: pointer to bool to indicate whether receive pause should be |
| 49 | + * enabled. |
| 50 | + * |
| 51 | + * Flow control is resolved according to our and the link partners |
| 52 | + * advertisements using the following drawn from the 802.3 specs: |
| 53 | + * Local device Link partner |
| 54 | + * Pause AsymDir Pause AsymDir Result |
| 55 | + * 0 X 0 X Disabled |
| 56 | + * 0 1 1 0 Disabled |
| 57 | + * 0 1 1 1 TX |
| 58 | + * 1 0 0 X Disabled |
| 59 | + * 1 X 1 X TX+RX |
| 60 | + * 1 1 0 1 RX |
| 61 | + */ |
| 62 | +void linkmode_resolve_pause(unsigned long *local_adv, |
| 63 | + unsigned long *partner_adv, |
| 64 | + bool *tx_pause, bool *rx_pause) |
| 65 | +{ |
| 66 | + __ETHTOOL_DECLARE_LINK_MODE_MASK(m); |
| 67 | + |
| 68 | + linkmode_and(m, local_adv, partner_adv); |
| 69 | + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, m)) { |
| 70 | + *tx_pause = true; |
| 71 | + *rx_pause = true; |
| 72 | + } else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, m)) { |
| 73 | + *tx_pause = linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
| 74 | + partner_adv); |
| 75 | + *rx_pause = linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
| 76 | + local_adv); |
| 77 | + } else { |
| 78 | + *tx_pause = false; |
| 79 | + *rx_pause = false; |
| 80 | + } |
| 81 | +} |
| 82 | +EXPORT_SYMBOL_GPL(linkmode_resolve_pause); |
| 83 | + |
| 84 | +/** |
| 85 | + * linkmode_set_pause - set the pause mode advertisement |
| 86 | + * @advertisement: advertisement in ethtool format |
| 87 | + * @tx: boolean from ethtool struct ethtool_pauseparam tx_pause member |
| 88 | + * @rx: boolean from ethtool struct ethtool_pauseparam rx_pause member |
| 89 | + * |
| 90 | + * Configure the advertised Pause and Asym_Pause bits according to the |
| 91 | + * capabilities of provided in @tx and @rx. |
| 92 | + * |
| 93 | + * We convert as follows: |
| 94 | + * tx rx Pause AsymDir |
| 95 | + * 0 0 0 0 |
| 96 | + * 0 1 1 1 |
| 97 | + * 1 0 0 1 |
| 98 | + * 1 1 1 0 |
| 99 | + * |
| 100 | + * Note: this translation from ethtool tx/rx notation to the advertisement |
| 101 | + * is actually very problematical. Here are some examples: |
| 102 | + * |
| 103 | + * For tx=0 rx=1, meaning transmit is unsupported, receive is supported: |
| 104 | + * |
| 105 | + * Local device Link partner |
| 106 | + * Pause AsymDir Pause AsymDir Result |
| 107 | + * 1 1 1 0 TX + RX - but we have no TX support. |
| 108 | + * 1 1 0 1 Only this gives RX only |
| 109 | + * |
| 110 | + * For tx=1 rx=1, meaning we have the capability to transmit and receive |
| 111 | + * pause frames: |
| 112 | + * |
| 113 | + * Local device Link partner |
| 114 | + * Pause AsymDir Pause AsymDir Result |
| 115 | + * 1 0 0 1 Disabled - but since we do support tx and rx, |
| 116 | + * this should resolve to RX only. |
| 117 | + * |
| 118 | + * Hence, asking for: |
| 119 | + * rx=1 tx=0 gives Pause+AsymDir advertisement, but we may end up |
| 120 | + * resolving to tx+rx pause or only rx pause depending on |
| 121 | + * the partners advertisement. |
| 122 | + * rx=0 tx=1 gives AsymDir only, which will only give tx pause if |
| 123 | + * the partners advertisement allows it. |
| 124 | + * rx=1 tx=1 gives Pause only, which will only allow tx+rx pause |
| 125 | + * if the other end also advertises Pause. |
| 126 | + */ |
| 127 | +void linkmode_set_pause(unsigned long *advertisement, bool tx, bool rx) |
| 128 | +{ |
| 129 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertisement, rx); |
| 130 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertisement, |
| 131 | + rx ^ tx); |
| 132 | +} |
| 133 | +EXPORT_SYMBOL_GPL(linkmode_set_pause); |
| 134 | diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 135 | index 9c76517ea..6b63b9839 100644 |
developer | 38afb1a | 2023-04-17 09:57:27 +0800 | [diff] [blame] | 136 | --- a/drivers/net/phy/phylink.c |
| 137 | +++ b/drivers/net/phy/phylink.c |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 138 | @@ -2185,4 +2185,192 @@ void phylink_helper_basex_speed(struct phylink_link_state *state) |
developer | 38afb1a | 2023-04-17 09:57:27 +0800 | [diff] [blame] | 139 | } |
| 140 | EXPORT_SYMBOL_GPL(phylink_helper_basex_speed); |
| 141 | |
| 142 | +static void phylink_decode_c37_word(struct phylink_link_state *state, |
| 143 | + uint16_t config_reg, int speed) |
| 144 | +{ |
| 145 | + bool tx_pause, rx_pause; |
| 146 | + int fd_bit; |
| 147 | + |
| 148 | + if (speed == SPEED_2500) |
| 149 | + fd_bit = ETHTOOL_LINK_MODE_2500baseX_Full_BIT; |
| 150 | + else |
| 151 | + fd_bit = ETHTOOL_LINK_MODE_1000baseX_Full_BIT; |
| 152 | + |
| 153 | + mii_lpa_mod_linkmode_x(state->lp_advertising, config_reg, fd_bit); |
| 154 | + |
| 155 | + if (linkmode_test_bit(fd_bit, state->advertising) && |
| 156 | + linkmode_test_bit(fd_bit, state->lp_advertising)) { |
| 157 | + state->speed = speed; |
| 158 | + state->duplex = DUPLEX_FULL; |
| 159 | + } else { |
| 160 | + /* negotiation failure */ |
| 161 | + state->link = false; |
| 162 | + } |
| 163 | + |
| 164 | + linkmode_resolve_pause(state->advertising, state->lp_advertising, |
| 165 | + &tx_pause, &rx_pause); |
| 166 | + |
| 167 | + if (tx_pause) |
| 168 | + state->pause |= MLO_PAUSE_TX; |
| 169 | + if (rx_pause) |
| 170 | + state->pause |= MLO_PAUSE_RX; |
| 171 | +} |
| 172 | + |
| 173 | +static void phylink_decode_sgmii_word(struct phylink_link_state *state, |
| 174 | + uint16_t config_reg) |
| 175 | +{ |
| 176 | + if (!(config_reg & LPA_SGMII_LINK)) { |
| 177 | + state->link = false; |
| 178 | + return; |
| 179 | + } |
| 180 | + |
| 181 | + switch (config_reg & LPA_SGMII_SPD_MASK) { |
| 182 | + case LPA_SGMII_10: |
| 183 | + state->speed = SPEED_10; |
| 184 | + break; |
| 185 | + case LPA_SGMII_100: |
| 186 | + state->speed = SPEED_100; |
| 187 | + break; |
| 188 | + case LPA_SGMII_1000: |
| 189 | + state->speed = SPEED_1000; |
| 190 | + break; |
| 191 | + default: |
| 192 | + state->link = false; |
| 193 | + return; |
| 194 | + } |
| 195 | + if (config_reg & LPA_SGMII_FULL_DUPLEX) |
| 196 | + state->duplex = DUPLEX_FULL; |
| 197 | + else |
| 198 | + state->duplex = DUPLEX_HALF; |
| 199 | +} |
| 200 | + |
| 201 | +/** |
| 202 | + * phylink_decode_usxgmii_word() - decode the USXGMII word from a MAC PCS |
| 203 | + * @state: a pointer to a struct phylink_link_state. |
| 204 | + * @lpa: a 16 bit value which stores the USXGMII auto-negotiation word |
| 205 | + * |
| 206 | + * Helper for MAC PCS supporting the USXGMII protocol and the auto-negotiation |
| 207 | + * code word. Decode the USXGMII code word and populate the corresponding fields |
| 208 | + * (speed, duplex) into the phylink_link_state structure. |
| 209 | + */ |
| 210 | +void phylink_decode_usxgmii_word(struct phylink_link_state *state, |
| 211 | + uint16_t lpa) |
| 212 | +{ |
| 213 | + switch (lpa & MDIO_USXGMII_SPD_MASK) { |
| 214 | + case MDIO_USXGMII_10: |
| 215 | + state->speed = SPEED_10; |
| 216 | + break; |
| 217 | + case MDIO_USXGMII_100: |
| 218 | + state->speed = SPEED_100; |
| 219 | + break; |
| 220 | + case MDIO_USXGMII_1000: |
| 221 | + state->speed = SPEED_1000; |
| 222 | + break; |
| 223 | + case MDIO_USXGMII_2500: |
| 224 | + state->speed = SPEED_2500; |
| 225 | + break; |
| 226 | + case MDIO_USXGMII_5000: |
| 227 | + state->speed = SPEED_5000; |
| 228 | + break; |
| 229 | + case MDIO_USXGMII_10G: |
| 230 | + state->speed = SPEED_10000; |
| 231 | + break; |
| 232 | + default: |
| 233 | + state->link = false; |
| 234 | + return; |
| 235 | + } |
| 236 | + |
| 237 | + if (lpa & MDIO_USXGMII_FULL_DUPLEX) |
| 238 | + state->duplex = DUPLEX_FULL; |
| 239 | + else |
| 240 | + state->duplex = DUPLEX_HALF; |
| 241 | +} |
| 242 | +EXPORT_SYMBOL_GPL(phylink_decode_usxgmii_word); |
| 243 | + |
| 244 | +/** |
| 245 | + * phylink_mii_c22_pcs_decode_state() - Decode MAC PCS state from MII registers |
| 246 | + * @state: a pointer to a &struct phylink_link_state. |
| 247 | + * @bmsr: The value of the %MII_BMSR register |
| 248 | + * @lpa: The value of the %MII_LPA register |
| 249 | + * |
| 250 | + * Helper for MAC PCS supporting the 802.3 clause 22 register set for |
| 251 | + * clause 37 negotiation and/or SGMII control. |
| 252 | + * |
| 253 | + * Parse the Clause 37 or Cisco SGMII link partner negotiation word into |
| 254 | + * the phylink @state structure. This is suitable to be used for implementing |
| 255 | + * the mac_pcs_get_state() member of the struct phylink_mac_ops structure if |
| 256 | + * accessing @bmsr and @lpa cannot be done with MDIO directly. |
| 257 | + */ |
| 258 | +void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state, |
| 259 | + u16 bmsr, u16 lpa) |
| 260 | +{ |
| 261 | + state->link = !!(bmsr & BMSR_LSTATUS); |
| 262 | + state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE); |
| 263 | + /* If there is no link or autonegotiation is disabled, the LP advertisement |
| 264 | + * data is not meaningful, so don't go any further. |
| 265 | + */ |
| 266 | + if (!state->link || !state->an_enabled) |
| 267 | + return; |
| 268 | + |
| 269 | + switch (state->interface) { |
| 270 | + case PHY_INTERFACE_MODE_1000BASEX: |
| 271 | + phylink_decode_c37_word(state, lpa, SPEED_1000); |
| 272 | + break; |
| 273 | + |
| 274 | + case PHY_INTERFACE_MODE_2500BASEX: |
| 275 | + phylink_decode_c37_word(state, lpa, SPEED_2500); |
| 276 | + break; |
| 277 | + |
| 278 | + case PHY_INTERFACE_MODE_SGMII: |
| 279 | + case PHY_INTERFACE_MODE_QSGMII: |
| 280 | + phylink_decode_sgmii_word(state, lpa); |
| 281 | + break; |
| 282 | + |
| 283 | + default: |
| 284 | + state->link = false; |
| 285 | + break; |
| 286 | + } |
| 287 | +} |
| 288 | +EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_decode_state); |
| 289 | + |
| 290 | +/** |
| 291 | + * phylink_mii_c22_pcs_encode_advertisement() - configure the clause 37 PCS |
| 292 | + * advertisement |
| 293 | + * @interface: the PHY interface mode being configured |
| 294 | + * @advertising: the ethtool advertisement mask |
| 295 | + * |
| 296 | + * Helper for MAC PCS supporting the 802.3 clause 22 register set for |
| 297 | + * clause 37 negotiation and/or SGMII control. |
| 298 | + * |
| 299 | + * Encode the clause 37 PCS advertisement as specified by @interface and |
| 300 | + * @advertising. |
| 301 | + * |
| 302 | + * Return: The new value for @adv, or ``-EINVAL`` if it should not be changed. |
| 303 | + */ |
| 304 | +int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface, |
| 305 | + const unsigned long *advertising) |
| 306 | +{ |
| 307 | + u16 adv; |
| 308 | + |
| 309 | + switch (interface) { |
| 310 | + case PHY_INTERFACE_MODE_1000BASEX: |
| 311 | + case PHY_INTERFACE_MODE_2500BASEX: |
| 312 | + adv = ADVERTISE_1000XFULL; |
| 313 | + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, |
| 314 | + advertising)) |
| 315 | + adv |= ADVERTISE_1000XPAUSE; |
| 316 | + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, |
| 317 | + advertising)) |
| 318 | + adv |= ADVERTISE_1000XPSE_ASYM; |
| 319 | + return adv; |
| 320 | + case PHY_INTERFACE_MODE_SGMII: |
| 321 | + case PHY_INTERFACE_MODE_QSGMII: |
| 322 | + return 0x0001; |
| 323 | + default: |
| 324 | + /* Nothing to do for other modes */ |
| 325 | + return -EINVAL; |
| 326 | + } |
| 327 | +} |
| 328 | +EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_encode_advertisement); |
| 329 | + |
| 330 | MODULE_LICENSE("GPL v2"); |
| 331 | diff --git a/include/linux/linkmode.h b/include/linux/linkmode.h |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 332 | index a99c58866..d38da4e89 100644 |
developer | 38afb1a | 2023-04-17 09:57:27 +0800 | [diff] [blame] | 333 | --- a/include/linux/linkmode.h |
| 334 | +++ b/include/linux/linkmode.h |
| 335 | @@ -82,4 +82,10 @@ static inline int linkmode_equal(const unsigned long *src1, |
| 336 | return bitmap_equal(src1, src2, __ETHTOOL_LINK_MODE_MASK_NBITS); |
| 337 | } |
| 338 | |
| 339 | +void linkmode_resolve_pause(unsigned long *local_adv, |
| 340 | + unsigned long *partner_adv, |
| 341 | + bool *tx_pause, bool *rx_pause); |
| 342 | + |
| 343 | +void linkmode_set_pause(unsigned long *advertisement, bool tx, bool rx); |
| 344 | + |
| 345 | #endif /* __LINKMODE_H */ |
| 346 | diff --git a/include/linux/mii.h b/include/linux/mii.h |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 347 | index 4ce8901a1..54b7f64b0 100644 |
developer | 38afb1a | 2023-04-17 09:57:27 +0800 | [diff] [blame] | 348 | --- a/include/linux/mii.h |
| 349 | +++ b/include/linux/mii.h |
| 350 | @@ -485,6 +485,45 @@ static inline u32 linkmode_adv_to_lcl_adv_t(unsigned long *advertising) |
| 351 | return lcl_adv; |
| 352 | } |
| 353 | |
| 354 | +/** |
| 355 | + * mii_lpa_mod_linkmode_x - decode the link partner's config_reg to linkmodes |
| 356 | + * @linkmodes: link modes array |
| 357 | + * @lpa: config_reg word from link partner |
| 358 | + * @fd_bit: link mode for 1000XFULL bit |
| 359 | + */ |
| 360 | +static inline void mii_lpa_mod_linkmode_x(unsigned long *linkmodes, u16 lpa, |
| 361 | + int fd_bit) |
| 362 | +{ |
| 363 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, linkmodes, |
| 364 | + lpa & LPA_LPACK); |
| 365 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, linkmodes, |
| 366 | + lpa & LPA_1000XPAUSE); |
| 367 | + linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes, |
| 368 | + lpa & LPA_1000XPAUSE_ASYM); |
| 369 | + linkmode_mod_bit(fd_bit, linkmodes, |
| 370 | + lpa & LPA_1000XFULL); |
| 371 | +} |
| 372 | + |
| 373 | +/** |
| 374 | + * linkmode_adv_to_mii_adv_x - encode a linkmode to config_reg |
| 375 | + * @linkmodes: linkmodes |
| 376 | + * @fd_bit: full duplex bit |
| 377 | + */ |
| 378 | +static inline u16 linkmode_adv_to_mii_adv_x(unsigned long *linkmodes, |
| 379 | + int fd_bit) |
| 380 | +{ |
| 381 | + u16 adv = 0; |
| 382 | + |
| 383 | + if (linkmode_test_bit(fd_bit, linkmodes)) |
| 384 | + adv |= ADVERTISE_1000XFULL; |
| 385 | + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, linkmodes)) |
| 386 | + adv |= ADVERTISE_1000XPAUSE; |
| 387 | + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes)) |
| 388 | + adv |= ADVERTISE_1000XPSE_ASYM; |
| 389 | + |
| 390 | + return adv; |
| 391 | +} |
| 392 | + |
| 393 | /** |
| 394 | * mii_advertise_flowctrl - get flow control advertisement flags |
| 395 | * @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both) |
| 396 | diff --git a/include/linux/phylink.h b/include/linux/phylink.h |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 397 | index ba0f09d02..48ff9fead 100644 |
developer | 38afb1a | 2023-04-17 09:57:27 +0800 | [diff] [blame] | 398 | --- a/include/linux/phylink.h |
| 399 | +++ b/include/linux/phylink.h |
| 400 | @@ -490,4 +490,34 @@ int phylink_mii_ioctl(struct phylink *, struct ifreq *, int); |
| 401 | void phylink_set_port_modes(unsigned long *bits); |
| 402 | void phylink_helper_basex_speed(struct phylink_link_state *state); |
| 403 | |
| 404 | +/** |
| 405 | + * phylink_get_link_timer_ns - return the PCS link timer value |
| 406 | + * @interface: link &typedef phy_interface_t mode |
| 407 | + * |
| 408 | + * Return the PCS link timer setting in nanoseconds for the PHY @interface |
| 409 | + * mode, or -EINVAL if not appropriate. |
| 410 | + */ |
| 411 | +static inline int phylink_get_link_timer_ns(phy_interface_t interface) |
| 412 | +{ |
| 413 | + switch (interface) { |
| 414 | + case PHY_INTERFACE_MODE_SGMII: |
| 415 | + case PHY_INTERFACE_MODE_QSGMII: |
| 416 | + case PHY_INTERFACE_MODE_USXGMII: |
| 417 | + return 1600000; |
| 418 | + |
| 419 | + case PHY_INTERFACE_MODE_1000BASEX: |
| 420 | + case PHY_INTERFACE_MODE_2500BASEX: |
| 421 | + return 10000000; |
| 422 | + |
| 423 | + default: |
| 424 | + return -EINVAL; |
| 425 | + } |
| 426 | +} |
| 427 | + |
| 428 | +void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state, |
| 429 | + u16 bmsr, u16 lpa); |
| 430 | +int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface, |
| 431 | + const unsigned long *advertising); |
| 432 | +void phylink_decode_usxgmii_word(struct phylink_link_state *state, |
| 433 | + uint16_t lpa); |
| 434 | #endif |
| 435 | diff --git a/include/uapi/linux/mdio.h b/include/uapi/linux/mdio.h |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 436 | index 4bcb41c71..3f302e252 100644 |
developer | 38afb1a | 2023-04-17 09:57:27 +0800 | [diff] [blame] | 437 | --- a/include/uapi/linux/mdio.h |
| 438 | +++ b/include/uapi/linux/mdio.h |
| 439 | @@ -324,4 +324,30 @@ static inline __u16 mdio_phy_id_c45(int prtad, int devad) |
| 440 | return MDIO_PHY_ID_C45 | (prtad << 5) | devad; |
| 441 | } |
| 442 | |
| 443 | +/* UsxgmiiChannelInfo[15:0] for USXGMII in-band auto-negotiation.*/ |
| 444 | +#define MDIO_USXGMII_EEE_CLK_STP 0x0080 /* EEE clock stop supported */ |
| 445 | +#define MDIO_USXGMII_EEE 0x0100 /* EEE supported */ |
| 446 | +#define MDIO_USXGMII_SPD_MASK 0x0e00 /* USXGMII speed mask */ |
| 447 | +#define MDIO_USXGMII_FULL_DUPLEX 0x1000 /* USXGMII full duplex */ |
| 448 | +#define MDIO_USXGMII_DPX_SPD_MASK 0x1e00 /* USXGMII duplex and speed bits */ |
| 449 | +#define MDIO_USXGMII_10 0x0000 /* 10Mbps */ |
| 450 | +#define MDIO_USXGMII_10HALF 0x0000 /* 10Mbps half-duplex */ |
| 451 | +#define MDIO_USXGMII_10FULL 0x1000 /* 10Mbps full-duplex */ |
| 452 | +#define MDIO_USXGMII_100 0x0200 /* 100Mbps */ |
| 453 | +#define MDIO_USXGMII_100HALF 0x0200 /* 100Mbps half-duplex */ |
| 454 | +#define MDIO_USXGMII_100FULL 0x1200 /* 100Mbps full-duplex */ |
| 455 | +#define MDIO_USXGMII_1000 0x0400 /* 1000Mbps */ |
| 456 | +#define MDIO_USXGMII_1000HALF 0x0400 /* 1000Mbps half-duplex */ |
| 457 | +#define MDIO_USXGMII_1000FULL 0x1400 /* 1000Mbps full-duplex */ |
| 458 | +#define MDIO_USXGMII_10G 0x0600 /* 10Gbps */ |
| 459 | +#define MDIO_USXGMII_10GHALF 0x0600 /* 10Gbps half-duplex */ |
| 460 | +#define MDIO_USXGMII_10GFULL 0x1600 /* 10Gbps full-duplex */ |
| 461 | +#define MDIO_USXGMII_2500 0x0800 /* 2500Mbps */ |
| 462 | +#define MDIO_USXGMII_2500HALF 0x0800 /* 2500Mbps half-duplex */ |
| 463 | +#define MDIO_USXGMII_2500FULL 0x1800 /* 2500Mbps full-duplex */ |
| 464 | +#define MDIO_USXGMII_5000 0x0a00 /* 5000Mbps */ |
| 465 | +#define MDIO_USXGMII_5000HALF 0x0a00 /* 5000Mbps half-duplex */ |
| 466 | +#define MDIO_USXGMII_5000FULL 0x1a00 /* 5000Mbps full-duplex */ |
| 467 | +#define MDIO_USXGMII_LINK 0x8000 /* PHY link with copper-side partner */ |
| 468 | + |
| 469 | #endif /* _UAPI__LINUX_MDIO_H__ */ |
| 470 | diff --git a/include/uapi/linux/mii.h b/include/uapi/linux/mii.h |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 471 | index 51b48e4be..90f9b4e1b 100644 |
developer | 38afb1a | 2023-04-17 09:57:27 +0800 | [diff] [blame] | 472 | --- a/include/uapi/linux/mii.h |
| 473 | +++ b/include/uapi/linux/mii.h |
| 474 | @@ -131,6 +131,23 @@ |
| 475 | #define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */ |
| 476 | #define NWAYTEST_RESV2 0xfe00 /* Unused... */ |
| 477 | |
| 478 | +/* MAC and PHY tx_config_Reg[15:0] for SGMII in-band auto-negotiation.*/ |
| 479 | +#define ADVERTISE_SGMII 0x0001 /* MAC can do SGMII */ |
| 480 | +#define LPA_SGMII 0x0001 /* PHY can do SGMII */ |
| 481 | +#define LPA_SGMII_SPD_MASK 0x0c00 /* SGMII speed mask */ |
| 482 | +#define LPA_SGMII_FULL_DUPLEX 0x1000 /* SGMII full duplex */ |
| 483 | +#define LPA_SGMII_DPX_SPD_MASK 0x1C00 /* SGMII duplex and speed bits */ |
| 484 | +#define LPA_SGMII_10 0x0000 /* 10Mbps */ |
| 485 | +#define LPA_SGMII_10HALF 0x0000 /* Can do 10mbps half-duplex */ |
| 486 | +#define LPA_SGMII_10FULL 0x1000 /* Can do 10mbps full-duplex */ |
| 487 | +#define LPA_SGMII_100 0x0400 /* 100Mbps */ |
| 488 | +#define LPA_SGMII_100HALF 0x0400 /* Can do 100mbps half-duplex */ |
| 489 | +#define LPA_SGMII_100FULL 0x1400 /* Can do 100mbps full-duplex */ |
| 490 | +#define LPA_SGMII_1000 0x0800 /* 1000Mbps */ |
| 491 | +#define LPA_SGMII_1000HALF 0x0800 /* Can do 1000mbps half-duplex */ |
| 492 | +#define LPA_SGMII_1000FULL 0x1800 /* Can do 1000mbps full-duplex */ |
| 493 | +#define LPA_SGMII_LINK 0x8000 /* PHY link with copper-side partner */ |
| 494 | + |
| 495 | /* 1000BASE-T Control register */ |
| 496 | #define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ |
| 497 | #define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */ |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 498 | -- |
| 499 | 2.34.1 |
| 500 | |