drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c- Extension
.c- Size
- 8776 bytes
- Lines
- 332
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk.hlinux/of_address.hlinux/of_mdio.hlinux/jiffies.hlinux/iopoll.hxilinx_axienet.h
Detected Declarations
function Copyrightfunction axienet_mdio_mdc_enablefunction axienet_mdio_mdc_disablefunction axienet_mdio_readfunction axienet_mdio_writefunction axienet_mdio_enablefunction axienet_mdio_setupfunction axienet_mdio_teardown
Annotated Snippet
if (!np1) {
netdev_warn(lp->ndev, "Could not find CPU device node.\n");
host_clock = DEFAULT_HOST_CLOCK;
} else {
int ret = of_property_read_u32(np1, "clock-frequency",
&host_clock);
if (ret) {
netdev_warn(lp->ndev, "CPU clock-frequency property not found.\n");
host_clock = DEFAULT_HOST_CLOCK;
}
of_node_put(np1);
}
netdev_info(lp->ndev, "Setting assumed host clock to %u\n",
host_clock);
}
if (np)
of_property_read_u32(np, "clock-frequency", &mdio_freq);
if (mdio_freq != DEFAULT_MDIO_FREQ)
netdev_info(lp->ndev, "Setting non-standard mdio bus frequency to %u Hz\n",
mdio_freq);
/* clk_div can be calculated by deriving it from the equation:
* fMDIO = fHOST / ((1 + clk_div) * 2)
*
* Where fMDIO <= 2500000, so we get:
* fHOST / ((1 + clk_div) * 2) <= 2500000
*
* Then we get:
* 1 / ((1 + clk_div) * 2) <= (2500000 / fHOST)
*
* Then we get:
* 1 / (1 + clk_div) <= ((2500000 * 2) / fHOST)
*
* Then we get:
* 1 / (1 + clk_div) <= (5000000 / fHOST)
*
* So:
* (1 + clk_div) >= (fHOST / 5000000)
*
* And finally:
* clk_div >= (fHOST / 5000000) - 1
*
* fHOST can be read from the flattened device tree as property
* "clock-frequency" from the CPU
*/
clk_div = (host_clock / (mdio_freq * 2)) - 1;
/* If there is any remainder from the division of
* fHOST / (mdio_freq * 2), then we need to add
* 1 to the clock divisor or we will surely be
* above the requested frequency
*/
if (host_clock % (mdio_freq * 2))
clk_div++;
/* Check for overflow of mii_clk_div */
if (clk_div & ~XAE_MDIO_MC_CLOCK_DIVIDE_MAX) {
netdev_warn(lp->ndev, "MDIO clock divisor overflow\n");
return -EOVERFLOW;
}
lp->mii_clk_div = (u8)clk_div;
netdev_dbg(lp->ndev,
"Setting MDIO clock divisor to %u/%u Hz host clock.\n",
lp->mii_clk_div, host_clock);
axienet_mdio_mdc_enable(lp);
ret = axienet_mdio_wait_until_ready(lp);
if (ret)
axienet_mdio_mdc_disable(lp);
return ret;
}
/**
* axienet_mdio_setup - MDIO setup function
* @lp: Pointer to axienet local data structure.
*
* Return: 0 on success, -ETIMEDOUT on a timeout, -EOVERFLOW on a clock
* divisor overflow, -ENOMEM when mdiobus_alloc (to allocate
* memory for mii bus structure) fails.
*
* Sets up the MDIO interface by initializing the MDIO clock.
* Register the MDIO interface.
**/
int axienet_mdio_setup(struct axienet_local *lp)
{
struct device_node *mdio_node;
Annotation
- Immediate include surface: `linux/clk.h`, `linux/of_address.h`, `linux/of_mdio.h`, `linux/jiffies.h`, `linux/iopoll.h`, `xilinx_axienet.h`.
- Detected declarations: `function Copyright`, `function axienet_mdio_mdc_enable`, `function axienet_mdio_mdc_disable`, `function axienet_mdio_read`, `function axienet_mdio_write`, `function axienet_mdio_enable`, `function axienet_mdio_setup`, `function axienet_mdio_teardown`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source 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.