drivers/net/phy/phy_caps.c
Source file repositories/reference/linux-study-clean/drivers/net/phy/phy_caps.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/phy/phy_caps.c- Extension
.c- Size
- 13671 bytes
- Lines
- 448
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/ethtool.hlinux/linkmode.hlinux/phy.hphy-caps.h
Detected Declarations
function speed_duplex_to_capafunction phy_caps_initfunction phy_caps_speedsfunction for_each_link_caps_asc_speedfunction phy_caps_lookup_by_linkmodefunction phy_caps_lookup_by_linkmode_revfunction for_each_link_caps_asc_speedfunction phy_caps_lookupfunction for_each_link_caps_desc_speedfunction phy_caps_linkmode_max_speedfunction phy_caps_validfunction phy_caps_linkmodesfunction phy_caps_from_interfacefunction phy_caps_medium_get_supportedfunction phy_caps_mediums_from_linkmodesfunction for_each_set_bitexport phy_caps_lookupexport phy_caps_linkmodesexport phy_caps_from_interfaceexport phy_caps_medium_get_supportedexport phy_caps_mediums_from_linkmodes
Annotated Snippet
if (linkmode->pairs < linkmode->min_pairs) {
pr_err("Pairs count must not be under min_pairs for linkmode %d\n",
i);
return -EINVAL;
}
capa = speed_duplex_to_capa(linkmode->speed, linkmode->duplex);
if (capa < 0) {
if (linkmode->speed != SPEED_UNKNOWN) {
pr_err("Unknown speed %d, please update LINK_CAPS\n",
linkmode->speed);
return -EINVAL;
}
continue;
}
__set_bit(i, link_caps[capa].linkmodes);
}
return 0;
}
/**
* 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(unsigned int *speeds, size_t size,
unsigned long *linkmodes)
{
struct link_capabilities *lcap;
size_t count = 0;
for_each_link_caps_asc_speed(lcap) {
if (linkmode_intersects(lcap->linkmodes, linkmodes) &&
(count == 0 || speeds[count - 1] != lcap->speed)) {
speeds[count++] = lcap->speed;
if (count >= size)
break;
}
}
return count;
}
/**
* 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.
*/
const struct link_capabilities *
phy_caps_lookup_by_linkmode(const unsigned long *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.
*/
const struct link_capabilities *
phy_caps_lookup_by_linkmode_rev(const unsigned long *linkmodes, bool fdx_only)
{
struct link_capabilities *lcap;
for_each_link_caps_asc_speed(lcap) {
if (fdx_only && lcap->duplex != DUPLEX_FULL)
continue;
Annotation
- Immediate include surface: `linux/ethtool.h`, `linux/linkmode.h`, `linux/phy.h`, `phy-caps.h`.
- Detected declarations: `function speed_duplex_to_capa`, `function phy_caps_init`, `function phy_caps_speeds`, `function for_each_link_caps_asc_speed`, `function phy_caps_lookup_by_linkmode`, `function phy_caps_lookup_by_linkmode_rev`, `function for_each_link_caps_asc_speed`, `function phy_caps_lookup`, `function for_each_link_caps_desc_speed`, `function phy_caps_linkmode_max_speed`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: integration implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.