switch (speed) { case SPEED_10: return duplex == DUPLEX_FULL ?
LINK_CAPA_10FD : LINK_CAPA_10HD; case SPEED_100: return duplex == DUPLEX_FULL ?
LINK_CAPA_100FD : LINK_CAPA_100HD; case SPEED_1000: return duplex == DUPLEX_FULL ?
LINK_CAPA_1000FD : LINK_CAPA_1000HD; case SPEED_2500: return LINK_CAPA_2500FD; case SPEED_5000: return LINK_CAPA_5000FD; case SPEED_10000: return LINK_CAPA_10000FD; case SPEED_20000: return LINK_CAPA_20000FD; case SPEED_25000: return LINK_CAPA_25000FD; case SPEED_40000: return LINK_CAPA_40000FD; case SPEED_50000: return LINK_CAPA_50000FD; case SPEED_56000: return LINK_CAPA_56000FD; case SPEED_100000: return LINK_CAPA_100000FD; case SPEED_200000: return LINK_CAPA_200000FD; case SPEED_400000: return LINK_CAPA_400000FD; case SPEED_800000: return LINK_CAPA_800000FD;
}
return -EINVAL;
}
#define for_each_link_caps_asc_speed(cap) \ for (cap = link_caps; cap < &link_caps[__LINK_CAPA_MAX]; cap++)
#define for_each_link_caps_desc_speed(cap) \ for (cap = &link_caps[__LINK_CAPA_MAX - 1]; cap >= link_caps; cap--)
/** * phy_caps_init() - Initializes the link_caps array from the link_mode_params. * * Returns: 0 if phy caps init was successful, -EINVAL if we found an * unexpected linkmode setting that requires LINK_CAPS update. *
*/ int phy_caps_init(void)
{ conststruct link_mode_info *linkmode; int i, capa;
/* Fill the caps array from net/ethtool/common.c */ for (i = 0; i < __ETHTOOL_LINK_MODE_MASK_NBITS; i++) {
linkmode = &link_mode_params[i];
capa = speed_duplex_to_capa(linkmode->speed, linkmode->duplex);
/** * phy_caps_speeds() - Fill an array of supported SPEED_* values for given modes * @speeds: Output array to store the speeds list into * @size: Size of the output array * @linkmodes: Linkmodes to get the speeds from * * Fills the speeds array with all possible speeds that can be achieved with * the specified linkmodes. * * Returns: The number of speeds filled into the array. If the input array isn't * big enough to store all speeds, fill it as much as possible.
*/
size_t phy_caps_speeds(unsignedint *speeds, size_t size, unsignedlong *linkmodes)
{ struct link_capabilities *lcap;
size_t count = 0;
/** * phy_caps_lookup_by_linkmode() - Lookup the fastest matching link_capabilities * @linkmodes: Linkmodes to match against * * Returns: The highest-speed link_capabilities that intersects the given * linkmodes. In case several DUPLEX_ options exist at that speed, * DUPLEX_FULL is matched first. NULL is returned if no match.
*/ conststruct link_capabilities *
phy_caps_lookup_by_linkmode(constunsignedlong *linkmodes)
{ struct link_capabilities *lcap;
for_each_link_caps_desc_speed(lcap) if (linkmode_intersects(lcap->linkmodes, linkmodes)) return lcap;
return NULL;
}
/** * phy_caps_lookup_by_linkmode_rev() - Lookup the slowest matching link_capabilities * @linkmodes: Linkmodes to match against * @fdx_only: Full duplex match only when set * * Returns: The lowest-speed link_capabilities that intersects the given * linkmodes. When set, fdx_only will ignore half-duplex matches. * NULL is returned if no match.
*/ conststruct link_capabilities *
phy_caps_lookup_by_linkmode_rev(constunsignedlong *linkmodes, bool fdx_only)
{ struct link_capabilities *lcap;
for_each_link_caps_asc_speed(lcap) { if (fdx_only && lcap->duplex != DUPLEX_FULL) continue;
if (linkmode_intersects(lcap->linkmodes, linkmodes)) return lcap;
}
return NULL;
}
/** * phy_caps_lookup() - Lookup capabilities by speed/duplex that matches a mask * @speed: Speed to match * @duplex: Duplex to match * @supported: Mask of linkmodes to match * @exact: Perform an exact match or not. * * Lookup a link_capabilities entry that intersect the supported linkmodes mask, * and that matches the passed speed and duplex. * * When @exact is set, an exact match is performed on speed and duplex, meaning * that if the linkmodes for the given speed and duplex intersect the supported * mask, this capability is returned, otherwise we don't have a match and return * NULL. * * When @exact is not set, we return either an exact match, or matching capabilities * at lower speed, or the lowest matching speed, or NULL. * * Non-exact matches will try to return an exact speed and duplex match, but may * return matching capabilities with same speed but a different duplex. * * Returns: a matched link_capabilities according to the above process, NULL * otherwise.
*/ conststruct link_capabilities *
phy_caps_lookup(int speed, unsignedint duplex, constunsignedlong *supported, bool exact)
{ conststruct link_capabilities *lcap, *match = NULL, *last = NULL;
for_each_link_caps_desc_speed(lcap) { if (linkmode_intersects(lcap->linkmodes, supported)) {
last = lcap; /* exact match on speed and duplex*/ if (lcap->speed == speed && lcap->duplex == duplex) { return lcap;
} elseif (!exact) { if (!match && lcap->speed <= speed)
match = lcap;
/** * phy_caps_linkmode_max_speed() - Clamp a linkmodes set to a max speed * @max_speed: Speed limit for the linkmode set * @linkmodes: Linkmodes to limit
*/ void phy_caps_linkmode_max_speed(u32 max_speed, unsignedlong *linkmodes)
{ struct link_capabilities *lcap;
/** * phy_caps_valid() - Validate a linkmodes set agains given speed and duplex * @speed: input speed to validate * @duplex: input duplex to validate. Passing DUPLEX_UNKNOWN is always not valid * @linkmodes: The linkmodes to validate * * Returns: True if at least one of the linkmodes in @linkmodes can function at * the given speed and duplex, false otherwise.
*/ bool phy_caps_valid(int speed, int duplex, constunsignedlong *linkmodes)
{ int capa = speed_duplex_to_capa(speed, duplex);
/** * phy_caps_linkmodes() - Convert a bitfield of capabilities into linkmodes * @caps: The list of caps, each bit corresponding to a LINK_CAPA value * @linkmodes: The set of linkmodes to fill. Must be previously initialized.
*/ void phy_caps_linkmodes(unsignedlong caps, unsignedlong *linkmodes)
{ unsignedlong capa;
/** * phy_caps_from_interface() - Get the link capa from a given PHY interface * @interface: The PHY interface we want to get the possible Speed/Duplex from * * Returns: A bitmask of LINK_CAPA_xxx values that can be achieved with the * provided interface.
*/ unsignedlong phy_caps_from_interface(phy_interface_t interface)
{ unsignedlong link_caps = 0;
case PHY_INTERFACE_MODE_10G_QXGMII:
link_caps |= BIT(LINK_CAPA_2500FD);
fallthrough;
case PHY_INTERFACE_MODE_RGMII_TXID: case PHY_INTERFACE_MODE_RGMII_RXID: case PHY_INTERFACE_MODE_RGMII_ID: case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_PSGMII: case PHY_INTERFACE_MODE_QSGMII: case PHY_INTERFACE_MODE_QUSGMII: case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_GMII:
link_caps |= BIT(LINK_CAPA_1000HD) | BIT(LINK_CAPA_1000FD);
fallthrough;
case PHY_INTERFACE_MODE_REVRMII: case PHY_INTERFACE_MODE_RMII: case PHY_INTERFACE_MODE_SMII: case PHY_INTERFACE_MODE_REVMII: case PHY_INTERFACE_MODE_MII:
link_caps |= BIT(LINK_CAPA_10HD) | BIT(LINK_CAPA_10FD);
fallthrough;
case PHY_INTERFACE_MODE_100BASEX:
link_caps |= BIT(LINK_CAPA_100HD) | BIT(LINK_CAPA_100FD); break;
case PHY_INTERFACE_MODE_MIILITE:
link_caps |= BIT(LINK_CAPA_10FD) | BIT(LINK_CAPA_100FD); break;
case PHY_INTERFACE_MODE_TBI: case PHY_INTERFACE_MODE_MOCA: case PHY_INTERFACE_MODE_RTBI: case PHY_INTERFACE_MODE_1000BASEX:
link_caps |= BIT(LINK_CAPA_1000HD);
fallthrough; case PHY_INTERFACE_MODE_1000BASEKX: case PHY_INTERFACE_MODE_TRGMII:
link_caps |= BIT(LINK_CAPA_1000FD); break;
case PHY_INTERFACE_MODE_2500BASEX:
link_caps |= BIT(LINK_CAPA_2500FD); break;
case PHY_INTERFACE_MODE_5GBASER:
link_caps |= BIT(LINK_CAPA_5000FD); break;
case PHY_INTERFACE_MODE_XGMII: case PHY_INTERFACE_MODE_RXAUI: case PHY_INTERFACE_MODE_XAUI: case PHY_INTERFACE_MODE_10GBASER: case PHY_INTERFACE_MODE_10GKR:
link_caps |= BIT(LINK_CAPA_10000FD); break;
case PHY_INTERFACE_MODE_25GBASER:
link_caps |= BIT(LINK_CAPA_25000FD); break;
case PHY_INTERFACE_MODE_XLGMII:
link_caps |= BIT(LINK_CAPA_40000FD); break;
case PHY_INTERFACE_MODE_50GBASER: case PHY_INTERFACE_MODE_LAUI:
link_caps |= BIT(LINK_CAPA_50000FD); break;
case PHY_INTERFACE_MODE_100GBASEP:
link_caps |= BIT(LINK_CAPA_100000FD); break;
case PHY_INTERFACE_MODE_INTERNAL:
link_caps |= LINK_CAPA_ALL; break;
case PHY_INTERFACE_MODE_NA: case PHY_INTERFACE_MODE_MAX: break;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.