Russell King says: ==================== introduce generic phylink validation The various validate method implementations we have in phylink users have been quite repetitive but also prone to bugs. These patches introduce a generic implementation which relies solely on the supported_interfaces bitmap introduced during last cycle, and in the first patch, a bit array of MAC capabilities. MAC drivers are free to continue to do their own thing if they have special requirements - such as mvneta and mvpp2 which do not support 1000base-X without AN enabled. Most implementations currently in the kernel can be converted to call phylink_generic_validate() directly from the phylink MAC operations structure once they fill in the supported_interfaces and mac_capabilities members of phylink_config. This series introduces the generic implementation, and converts mvneta and mvpp2 to use it. ====================
Unified · Split
| @@ -3823,8 +3823,6 @@ static void mvneta_validate(struct phylink_config *config, · 3822 unmodified lines | |||
| 3823 | unsigned long *supported, | 3823 | unsigned long *supported, |
| 3824 | struct phylink_link_state *state) | 3824 | struct phylink_link_state *state) |
| 3825 | { | 3825 | { |
| 3826 | __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; | ||
| 3827 | |||
| 3828 | /* We only support QSGMII, SGMII, 802.3z and RGMII modes. | 3826 | /* We only support QSGMII, SGMII, 802.3z and RGMII modes. |
| 3829 | * When in 802.3z mode, we must have AN enabled: | 3827 | * When in 802.3z mode, we must have AN enabled: |
| 3830 | * "Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ... | 3828 | * "Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ... |
| @@ -3836,34 +3834,7 @@ static void mvneta_validate(struct phylink_config *config, · 5 unmodified lines | |||
| 3836 | return; | 3834 | return; |
| 3837 | } | 3835 | } |
| 3838 | 3836 | ||
| 3839 | /* Allow all the expected bits */ | 3837 | phylink_generic_validate(config, supported, state); |
| 3840 | phylink_set(mask, Autoneg); | ||
| 3841 | phylink_set_port_modes(mask); | ||
| 3842 | |||
| 3843 | /* Asymmetric pause is unsupported */ | ||
| 3844 | phylink_set(mask, Pause); | ||
| 3845 | |||
| 3846 | /* Half-duplex at speeds higher than 100Mbit is unsupported */ | ||
| 3847 | if (state->interface != PHY_INTERFACE_MODE_2500BASEX) { | ||
| 3848 | phylink_set(mask, 1000baseT_Full); | ||
| 3849 | phylink_set(mask, 1000baseX_Full); | ||
| 3850 | } | ||
| 3851 | |||
| 3852 | if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { | ||
| 3853 | phylink_set(mask, 2500baseT_Full); | ||
| 3854 | phylink_set(mask, 2500baseX_Full); | ||
| 3855 | } | ||
| 3856 | |||
| 3857 | if (!phy_interface_mode_is_8023z(state->interface)) { | ||
| 3858 | /* 10M and 100M are only supported in non-802.3z mode */ | ||
| 3859 | phylink_set(mask, 10baseT_Half); | ||
| 3860 | phylink_set(mask, 10baseT_Full); | ||
| 3861 | phylink_set(mask, 100baseT_Half); | ||
| 3862 | phylink_set(mask, 100baseT_Full); | ||
| 3863 | } | ||
| 3864 | |||
| 3865 | linkmode_and(supported, supported, mask); | ||
| 3866 | linkmode_and(state->advertising, state->advertising, mask); | ||
| 3867 | } | 3838 | } |
| 3868 | 3839 | ||
| 3869 | static void mvneta_mac_pcs_get_state(struct phylink_config *config, | 3840 | static void mvneta_mac_pcs_get_state(struct phylink_config *config, |
| @@ -5166,6 +5137,9 @@ static int mvneta_probe(struct platform_device *pdev) · 1296 unmodified lines | |||
| 5166 | 5137 | ||
| 5167 | pp->phylink_config.dev = &dev->dev; | 5138 | pp->phylink_config.dev = &dev->dev; |
| 5168 | pp->phylink_config.type = PHYLINK_NETDEV; | 5139 | pp->phylink_config.type = PHYLINK_NETDEV; |
| 5140 | pp->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_10 | | ||
| 5141 | MAC_100 | MAC_1000FD | MAC_2500FD; | ||
| 5142 | |||
| 5169 | phy_interface_set_rgmii(pp->phylink_config.supported_interfaces); | 5143 | phy_interface_set_rgmii(pp->phylink_config.supported_interfaces); |
| 5170 | __set_bit(PHY_INTERFACE_MODE_QSGMII, | 5144 | __set_bit(PHY_INTERFACE_MODE_QSGMII, |
| 5171 | pp->phylink_config.supported_interfaces); | 5145 | pp->phylink_config.supported_interfaces); |
| @@ -6260,9 +6260,6 @@ static void mvpp2_phylink_validate(struct phylink_config *config, · 6259 unmodified lines | |||
| 6260 | unsigned long *supported, | 6260 | unsigned long *supported, |
| 6261 | struct phylink_link_state *state) | 6261 | struct phylink_link_state *state) |
| 6262 | { | 6262 | { |
| 6263 | struct mvpp2_port *port = mvpp2_phylink_to_port(config); | ||
| 6264 | __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; | ||
| 6265 | |||
| 6266 | /* When in 802.3z mode, we must have AN enabled: | 6263 | /* When in 802.3z mode, we must have AN enabled: |
| 6267 | * Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ... | 6264 | * Bit 2 Field InBandAnEn In-band Auto-Negotiation enable. ... |
| 6268 | * When <PortType> = 1 (1000BASE-X) this field must be set to 1. | 6265 | * When <PortType> = 1 (1000BASE-X) this field must be set to 1. |
| @@ -6271,52 +6268,7 @@ static void mvpp2_phylink_validate(struct phylink_config *config, · 2 unmodified lines | |||
| 6271 | !phylink_test(state->advertising, Autoneg)) | 6268 | !phylink_test(state->advertising, Autoneg)) |
| 6272 | goto empty_set; | 6269 | goto empty_set; |
| 6273 | 6270 | ||
| 6274 | phylink_set(mask, Autoneg); | 6271 | phylink_generic_validate(config, supported, state); |
| 6275 | phylink_set_port_modes(mask); | ||
| 6276 | |||
| 6277 | if (port->priv->global_tx_fc) { | ||
| 6278 | phylink_set(mask, Pause); | ||
| 6279 | phylink_set(mask, Asym_Pause); | ||
| 6280 | } | ||
| 6281 | |||
| 6282 | switch (state->interface) { | ||
| 6283 | case PHY_INTERFACE_MODE_10GBASER: | ||
| 6284 | case PHY_INTERFACE_MODE_XAUI: | ||
| 6285 | if (mvpp2_port_supports_xlg(port)) { | ||
| 6286 | phylink_set_10g_modes(mask); | ||
| 6287 | phylink_set(mask, 10000baseKR_Full); | ||
| 6288 | } | ||
| 6289 | break; | ||
| 6290 | |||
| 6291 | case PHY_INTERFACE_MODE_RGMII: | ||
| 6292 | case PHY_INTERFACE_MODE_RGMII_ID: | ||
| 6293 | case PHY_INTERFACE_MODE_RGMII_RXID: | ||
| 6294 | case PHY_INTERFACE_MODE_RGMII_TXID: | ||
| 6295 | case PHY_INTERFACE_MODE_SGMII: | ||
| 6296 | phylink_set(mask, 10baseT_Half); | ||
| 6297 | phylink_set(mask, 10baseT_Full); | ||
| 6298 | phylink_set(mask, 100baseT_Half); | ||
| 6299 | phylink_set(mask, 100baseT_Full); | ||
| 6300 | phylink_set(mask, 1000baseT_Full); | ||
| 6301 | phylink_set(mask, 1000baseX_Full); | ||
| 6302 | break; | ||
| 6303 | |||
| 6304 | case PHY_INTERFACE_MODE_1000BASEX: | ||
| 6305 | phylink_set(mask, 1000baseT_Full); | ||
| 6306 | phylink_set(mask, 1000baseX_Full); | ||
| 6307 | break; | ||
| 6308 | |||
| 6309 | case PHY_INTERFACE_MODE_2500BASEX: | ||
| 6310 | phylink_set(mask, 2500baseT_Full); | ||
| 6311 | phylink_set(mask, 2500baseX_Full); | ||
| 6312 | break; | ||
| 6313 | |||
| 6314 | default: | ||
| 6315 | goto empty_set; | ||
| 6316 | } | ||
| 6317 | |||
| 6318 | linkmode_and(supported, supported, mask); | ||
| 6319 | linkmode_and(state->advertising, state->advertising, mask); | ||
| 6320 | return; | 6272 | return; |
| 6321 | 6273 | ||
| 6322 | empty_set: | 6274 | empty_set: |
| @@ -6911,12 +6863,20 @@ static int mvpp2_port_probe(struct platform_device *pdev, · 588 unmodified lines | |||
| 6911 | if (!mvpp2_use_acpi_compat_mode(port_fwnode)) { | 6863 | if (!mvpp2_use_acpi_compat_mode(port_fwnode)) { |
| 6912 | port->phylink_config.dev = &dev->dev; | 6864 | port->phylink_config.dev = &dev->dev; |
| 6913 | port->phylink_config.type = PHYLINK_NETDEV; | 6865 | port->phylink_config.type = PHYLINK_NETDEV; |
| 6866 | port->phylink_config.mac_capabilities = | ||
| 6867 | MAC_2500FD | MAC_1000FD | MAC_100 | MAC_10; | ||
| 6868 | |||
| 6869 | if (port->priv->global_tx_fc) | ||
| 6870 | port->phylink_config.mac_capabilities |= | ||
| 6871 | MAC_SYM_PAUSE | MAC_ASYM_PAUSE; | ||
| 6914 | 6872 | ||
| 6915 | if (mvpp2_port_supports_xlg(port)) { | 6873 | if (mvpp2_port_supports_xlg(port)) { |
| 6916 | __set_bit(PHY_INTERFACE_MODE_10GBASER, | 6874 | __set_bit(PHY_INTERFACE_MODE_10GBASER, |
| 6917 | port->phylink_config.supported_interfaces); | 6875 | port->phylink_config.supported_interfaces); |
| 6918 | __set_bit(PHY_INTERFACE_MODE_XAUI, | 6876 | __set_bit(PHY_INTERFACE_MODE_XAUI, |
| 6919 | port->phylink_config.supported_interfaces); | 6877 | port->phylink_config.supported_interfaces); |
| 6878 | port->phylink_config.mac_capabilities |= | ||
| 6879 | MAC_10000FD; | ||
| 6920 | } | 6880 | } |
| 6921 | 6881 | ||
| 6922 | if (mvpp2_port_supports_rgmii(port)) | 6882 | if (mvpp2_port_supports_rgmii(port)) |
| @@ -166,6 +166,258 @@ static const char *phylink_an_mode_str(unsigned int mode) · 165 unmodified lines | |||
| 166 | return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown"; | 166 | return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown"; |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | static void phylink_caps_to_linkmodes(unsigned long *linkmodes, | ||
| 170 | unsigned long caps) | ||
| 171 | { | ||
| 172 | if (caps & MAC_SYM_PAUSE) | ||
| 173 | __set_bit(ETHTOOL_LINK_MODE_Pause_BIT, linkmodes); | ||
| 174 | |||
| 175 | if (caps & MAC_ASYM_PAUSE) | ||
| 176 | __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes); | ||
| 177 | |||
| 178 | if (caps & MAC_10HD) | ||
| 179 | __set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, linkmodes); | ||
| 180 | |||
| 181 | if (caps & MAC_10FD) | ||
| 182 | __set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, linkmodes); | ||
| 183 | |||
| 184 | if (caps & MAC_100HD) { | ||
| 185 | __set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, linkmodes); | ||
| 186 | __set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT, linkmodes); | ||
| 187 | } | ||
| 188 | |||
| 189 | if (caps & MAC_100FD) { | ||
| 190 | __set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, linkmodes); | ||
| 191 | __set_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT, linkmodes); | ||
| 192 | __set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, linkmodes); | ||
| 193 | } | ||
| 194 | |||
| 195 | if (caps & MAC_1000HD) | ||
| 196 | __set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, linkmodes); | ||
| 197 | |||
| 198 | if (caps & MAC_1000FD) { | ||
| 199 | __set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, linkmodes); | ||
| 200 | __set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, linkmodes); | ||
| 201 | __set_bit(ETHTOOL_LINK_MODE_1000baseT1_Full_BIT, linkmodes); | ||
| 202 | } | ||
| 203 | |||
| 204 | if (caps & MAC_2500FD) { | ||
| 205 | __set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, linkmodes); | ||
| 206 | __set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, linkmodes); | ||
| 207 | } | ||
| 208 | |||
| 209 | if (caps & MAC_5000FD) | ||
| 210 | __set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, linkmodes); | ||
| 211 | |||
| 212 | if (caps & MAC_10000FD) { | ||
| 213 | __set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, linkmodes); | ||
| 214 | __set_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, linkmodes); | ||
| 215 | __set_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, linkmodes); | ||
| 216 | __set_bit(ETHTOOL_LINK_MODE_10000baseR_FEC_BIT, linkmodes); | ||
| 217 | __set_bit(ETHTOOL_LINK_MODE_10000baseCR_Full_BIT, linkmodes); | ||
| 218 | __set_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, linkmodes); | ||
| 219 | __set_bit(ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, linkmodes); | ||
| 220 | __set_bit(ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT, linkmodes); | ||
| 221 | __set_bit(ETHTOOL_LINK_MODE_10000baseER_Full_BIT, linkmodes); | ||
| 222 | } | ||
| 223 | |||
| 224 | if (caps & MAC_25000FD) { | ||
| 225 | __set_bit(ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, linkmodes); | ||
| 226 | __set_bit(ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, linkmodes); | ||
| 227 | __set_bit(ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, linkmodes); | ||
| 228 | } | ||
| 229 | |||
| 230 | if (caps & MAC_40000FD) { | ||
| 231 | __set_bit(ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, linkmodes); | ||
| 232 | __set_bit(ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, linkmodes); | ||
| 233 | __set_bit(ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, linkmodes); | ||
| 234 | __set_bit(ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT, linkmodes); | ||
| 235 | } | ||
| 236 | |||
| 237 | if (caps & MAC_50000FD) { | ||
| 238 | __set_bit(ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT, linkmodes); | ||
| 239 | __set_bit(ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT, linkmodes); | ||
| 240 | __set_bit(ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, linkmodes); | ||
| 241 | __set_bit(ETHTOOL_LINK_MODE_50000baseKR_Full_BIT, linkmodes); | ||
| 242 | __set_bit(ETHTOOL_LINK_MODE_50000baseSR_Full_BIT, linkmodes); | ||
| 243 | __set_bit(ETHTOOL_LINK_MODE_50000baseCR_Full_BIT, linkmodes); | ||
| 244 | __set_bit(ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT, | ||
| 245 | linkmodes); | ||
| 246 | __set_bit(ETHTOOL_LINK_MODE_50000baseDR_Full_BIT, linkmodes); | ||
| 247 | } | ||
| 248 | |||
| 249 | if (caps & MAC_56000FD) { | ||
| 250 | __set_bit(ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT, linkmodes); | ||
| 251 | __set_bit(ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT, linkmodes); | ||
| 252 | __set_bit(ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT, linkmodes); | ||
| 253 | __set_bit(ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT, linkmodes); | ||
| 254 | } | ||
| 255 | |||
| 256 | if (caps & MAC_100000FD) { | ||
| 257 | __set_bit(ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, linkmodes); | ||
| 258 | __set_bit(ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, linkmodes); | ||
| 259 | __set_bit(ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, linkmodes); | ||
| 260 | __set_bit(ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT, | ||
| 261 | linkmodes); | ||
| 262 | __set_bit(ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT, linkmodes); | ||
| 263 | __set_bit(ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT, linkmodes); | ||
| 264 | __set_bit(ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT, linkmodes); | ||
| 265 | __set_bit(ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT, | ||
| 266 | linkmodes); | ||
| 267 | __set_bit(ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT, linkmodes); | ||
| 268 | __set_bit(ETHTOOL_LINK_MODE_100000baseKR_Full_BIT, linkmodes); | ||
| 269 | __set_bit(ETHTOOL_LINK_MODE_100000baseSR_Full_BIT, linkmodes); | ||
| 270 | __set_bit(ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT, | ||
| 271 | linkmodes); | ||
| 272 | __set_bit(ETHTOOL_LINK_MODE_100000baseCR_Full_BIT, linkmodes); | ||
| 273 | __set_bit(ETHTOOL_LINK_MODE_100000baseDR_Full_BIT, linkmodes); | ||
| 274 | } | ||
| 275 | |||
| 276 | if (caps & MAC_200000FD) { | ||
| 277 | __set_bit(ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT, linkmodes); | ||
| 278 | __set_bit(ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT, linkmodes); | ||
| 279 | __set_bit(ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT, | ||
| 280 | linkmodes); | ||
| 281 | __set_bit(ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT, linkmodes); | ||
| 282 | __set_bit(ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT, linkmodes); | ||
| 283 | __set_bit(ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT, linkmodes); | ||
| 284 | __set_bit(ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT, linkmodes); | ||
| 285 | __set_bit(ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT, | ||
| 286 | linkmodes); | ||
| 287 | __set_bit(ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT, linkmodes); | ||
| 288 | __set_bit(ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT, linkmodes); | ||
| 289 | } | ||
| 290 | |||
| 291 | if (caps & MAC_400000FD) { | ||
| 292 | __set_bit(ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT, linkmodes); | ||
| 293 | __set_bit(ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT, linkmodes); | ||
| 294 | __set_bit(ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT, | ||
| 295 | linkmodes); | ||
| 296 | __set_bit(ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT, linkmodes); | ||
| 297 | __set_bit(ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT, linkmodes); | ||
| 298 | __set_bit(ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT, linkmodes); | ||
| 299 | __set_bit(ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT, linkmodes); | ||
| 300 | __set_bit(ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT, | ||
| 301 | linkmodes); | ||
| 302 | __set_bit(ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT, linkmodes); | ||
| 303 | __set_bit(ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT, linkmodes); | ||
| 304 | } | ||
| 305 | } | ||
| 306 | |||
| 307 | /** | ||
| 308 | * phylink_get_linkmodes() - get acceptable link modes | ||
| 309 | * @linkmodes: ethtool linkmode mask (must be already initialised) | ||
| 310 | * @interface: phy interface mode defined by &typedef phy_interface_t | ||
| 311 | * @mac_capabilities: bitmask of MAC capabilities | ||
| 312 | * | ||
| 313 | * Set all possible pause, speed and duplex linkmodes in @linkmodes that | ||
| 314 | * are supported by the @interface mode and @mac_capabilities. @linkmodes | ||
| 315 | * must have been initialised previously. | ||
| 316 | */ | ||
| 317 | void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface, | ||
| 318 | unsigned long mac_capabilities) | ||
| 319 | { | ||
| 320 | unsigned long caps = MAC_SYM_PAUSE | MAC_ASYM_PAUSE; | ||
| 321 | |||
| 322 | switch (interface) { | ||
| 323 | case PHY_INTERFACE_MODE_USXGMII: | ||
| 324 | caps |= MAC_10000FD | MAC_5000FD | MAC_2500FD; | ||
| 325 | fallthrough; | ||
| 326 | |||
| 327 | case PHY_INTERFACE_MODE_RGMII_TXID: | ||
| 328 | case PHY_INTERFACE_MODE_RGMII_RXID: | ||
| 329 | case PHY_INTERFACE_MODE_RGMII_ID: | ||
| 330 | case PHY_INTERFACE_MODE_RGMII: | ||
| 331 | case PHY_INTERFACE_MODE_QSGMII: | ||
| 332 | case PHY_INTERFACE_MODE_SGMII: | ||
| 333 | case PHY_INTERFACE_MODE_GMII: | ||
| 334 | caps |= MAC_1000HD | MAC_1000FD; | ||
| 335 | fallthrough; | ||
| 336 | |||
| 337 | case PHY_INTERFACE_MODE_REVRMII: | ||
| 338 | case PHY_INTERFACE_MODE_RMII: | ||
| 339 | case PHY_INTERFACE_MODE_REVMII: | ||
| 340 | case PHY_INTERFACE_MODE_MII: | ||
| 341 | caps |= MAC_10HD | MAC_10FD; | ||
| 342 | fallthrough; | ||
| 343 | |||
| 344 | case PHY_INTERFACE_MODE_100BASEX: | ||
| 345 | caps |= MAC_100HD | MAC_100FD; | ||
| 346 | break; | ||
| 347 | |||
| 348 | case PHY_INTERFACE_MODE_TBI: | ||
| 349 | case PHY_INTERFACE_MODE_MOCA: | ||
| 350 | case PHY_INTERFACE_MODE_RTBI: | ||
| 351 | case PHY_INTERFACE_MODE_1000BASEX: | ||
| 352 | caps |= MAC_1000HD; | ||
| 353 | fallthrough; | ||
| 354 | case PHY_INTERFACE_MODE_TRGMII: | ||
| 355 | caps |= MAC_1000FD; | ||
| 356 | break; | ||
| 357 | |||
| 358 | case PHY_INTERFACE_MODE_2500BASEX: | ||
| 359 | caps |= MAC_2500FD; | ||
| 360 | break; | ||
| 361 | |||
| 362 | case PHY_INTERFACE_MODE_5GBASER: | ||
| 363 | caps |= MAC_5000FD; | ||
| 364 | break; | ||
| 365 | |||
| 366 | case PHY_INTERFACE_MODE_XGMII: | ||
| 367 | case PHY_INTERFACE_MODE_RXAUI: | ||
| 368 | case PHY_INTERFACE_MODE_XAUI: | ||
| 369 | case PHY_INTERFACE_MODE_10GBASER: | ||
| 370 | case PHY_INTERFACE_MODE_10GKR: | ||
| 371 | caps |= MAC_10000FD; | ||
| 372 | break; | ||
| 373 | |||
| 374 | case PHY_INTERFACE_MODE_25GBASER: | ||
| 375 | caps |= MAC_25000FD; | ||
| 376 | break; | ||
| 377 | |||
| 378 | case PHY_INTERFACE_MODE_XLGMII: | ||
| 379 | caps |= MAC_40000FD; | ||
| 380 | break; | ||
| 381 | |||
| 382 | case PHY_INTERFACE_MODE_INTERNAL: | ||
| 383 | caps |= ~0; | ||
| 384 | break; | ||
| 385 | |||
| 386 | case PHY_INTERFACE_MODE_NA: | ||
| 387 | case PHY_INTERFACE_MODE_MAX: | ||
| 388 | case PHY_INTERFACE_MODE_SMII: | ||
| 389 | break; | ||
| 390 | } | ||
| 391 | |||
| 392 | phylink_caps_to_linkmodes(linkmodes, caps & mac_capabilities); | ||
| 393 | } | ||
| 394 | EXPORT_SYMBOL_GPL(phylink_get_linkmodes); | ||
| 395 | |||
| 396 | /** | ||
| 397 | * phylink_generic_validate() - generic validate() callback implementation | ||
| 398 | * @config: a pointer to a &struct phylink_config. | ||
| 399 | * @supported: ethtool bitmask for supported link modes. | ||
| 400 | * @state: a pointer to a &struct phylink_link_state. | ||
| 401 | * | ||
| 402 | * Generic implementation of the validate() callback that MAC drivers can | ||
| 403 | * use when they pass the range of supported interfaces and MAC capabilities. | ||
| 404 | * This makes use of phylink_get_linkmodes(). | ||
| 405 | */ | ||
| 406 | void phylink_generic_validate(struct phylink_config *config, | ||
| 407 | unsigned long *supported, | ||
| 408 | struct phylink_link_state *state) | ||
| 409 | { | ||
| 410 | __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; | ||
| 411 | |||
| 412 | phylink_set_port_modes(mask); | ||
| 413 | phylink_set(mask, Autoneg); | ||
| 414 | phylink_get_linkmodes(mask, state->interface, config->mac_capabilities); | ||
| 415 | |||
| 416 | linkmode_and(supported, supported, mask); | ||
| 417 | linkmode_and(state->advertising, state->advertising, mask); | ||
| 418 | } | ||
| 419 | EXPORT_SYMBOL_GPL(phylink_generic_validate); | ||
| 420 | |||
| 169 | static int phylink_validate_any(struct phylink *pl, unsigned long *supported, | 421 | static int phylink_validate_any(struct phylink *pl, unsigned long *supported, |
| 170 | struct phylink_link_state *state) | 422 | struct phylink_link_state *state) |
| 171 | { | 423 | { |
| @@ -20,6 +20,29 @@ enum { · 19 unmodified lines | |||
| 20 | MLO_AN_PHY = 0, /* Conventional PHY */ | 20 | MLO_AN_PHY = 0, /* Conventional PHY */ |
| 21 | MLO_AN_FIXED, /* Fixed-link mode */ | 21 | MLO_AN_FIXED, /* Fixed-link mode */ |
| 22 | MLO_AN_INBAND, /* In-band protocol */ | 22 | MLO_AN_INBAND, /* In-band protocol */ |
| 23 | |||
| 24 | MAC_SYM_PAUSE = BIT(0), | ||
| 25 | MAC_ASYM_PAUSE = BIT(1), | ||
| 26 | MAC_10HD = BIT(2), | ||
| 27 | MAC_10FD = BIT(3), | ||
| 28 | MAC_10 = MAC_10HD | MAC_10FD, | ||
| 29 | MAC_100HD = BIT(4), | ||
| 30 | MAC_100FD = BIT(5), | ||
| 31 | MAC_100 = MAC_100HD | MAC_100FD, | ||
| 32 | MAC_1000HD = BIT(6), | ||
| 33 | MAC_1000FD = BIT(7), | ||
| 34 | MAC_1000 = MAC_1000HD | MAC_1000FD, | ||
| 35 | MAC_2500FD = BIT(8), | ||
| 36 | MAC_5000FD = BIT(9), | ||
| 37 | MAC_10000FD = BIT(10), | ||
| 38 | MAC_20000FD = BIT(11), | ||
| 39 | MAC_25000FD = BIT(12), | ||
| 40 | MAC_40000FD = BIT(13), | ||
| 41 | MAC_50000FD = BIT(14), | ||
| 42 | MAC_56000FD = BIT(15), | ||
| 43 | MAC_100000FD = BIT(16), | ||
| 44 | MAC_200000FD = BIT(17), | ||
| 45 | MAC_400000FD = BIT(18), | ||
| 23 | }; | 46 | }; |
| 24 | 47 | ||
| 25 | static inline bool phylink_autoneg_inband(unsigned int mode) | 48 | static inline bool phylink_autoneg_inband(unsigned int mode) |
| @@ -69,6 +92,7 @@ enum phylink_op_type { · 43 unmodified lines | |||
| 69 | * if MAC link is at %MLO_AN_FIXED mode. | 92 | * if MAC link is at %MLO_AN_FIXED mode. |
| 70 | * @supported_interfaces: bitmap describing which PHY_INTERFACE_MODE_xxx | 93 | * @supported_interfaces: bitmap describing which PHY_INTERFACE_MODE_xxx |
| 71 | * are supported by the MAC/PCS. | 94 | * are supported by the MAC/PCS. |
| 95 | * @mac_capabilities: MAC pause/speed/duplex capabilities. | ||
| 72 | */ | 96 | */ |
| 73 | struct phylink_config { | 97 | struct phylink_config { |
| 74 | struct device *dev; | 98 | struct device *dev; |
| @@ -79,6 +103,7 @@ struct phylink_config { · 4 unmodified lines | |||
| 79 | void (*get_fixed_state)(struct phylink_config *config, | 103 | void (*get_fixed_state)(struct phylink_config *config, |
| 80 | struct phylink_link_state *state); | 104 | struct phylink_link_state *state); |
| 81 | DECLARE_PHY_INTERFACE_MASK(supported_interfaces); | 105 | DECLARE_PHY_INTERFACE_MASK(supported_interfaces); |
| 106 | unsigned long mac_capabilities; | ||
| 82 | }; | 107 | }; |
| 83 | 108 | ||
| 84 | /** | 109 | /** |
| @@ -442,6 +467,12 @@ void pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, · 357 unmodified lines | |||
| 442 | phy_interface_t interface, int speed, int duplex); | 467 | phy_interface_t interface, int speed, int duplex); |
| 443 | #endif | 468 | #endif |
| 444 | 469 | ||
| 470 | void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface, | ||
| 471 | unsigned long mac_capabilities); | ||
| 472 | void phylink_generic_validate(struct phylink_config *config, | ||
| 473 | unsigned long *supported, | ||
| 474 | struct phylink_link_state *state); | ||
| 475 | |||
| 445 | struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *, | 476 | struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *, |
| 446 | phy_interface_t iface, | 477 | phy_interface_t iface, |
| 447 | const struct phylink_mac_ops *mac_ops); | 478 | const struct phylink_mac_ops *mac_ops); |