drivers/net/ethernet/microchip/lan865x/lan865x.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/microchip/lan865x/lan865x.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/microchip/lan865x/lan865x.c- Extension
.c- Size
- 11733 bytes
- Lines
- 456
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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 an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/kernel.hlinux/phy.hlinux/oa_tc6.h
Detected Declarations
struct lan865x_privfunction lan865x_set_hw_macaddr_low_bytesfunction lan865x_set_hw_macaddrfunction lan865x_set_mac_addressfunction get_address_bitfunction lan865x_hashfunction lan865x_set_specific_multicast_addrfunction netdev_for_each_mc_addrfunction lan865x_set_all_multicast_addrfunction lan865x_clear_all_multicast_addrfunction lan865x_multicast_work_handlerfunction lan865x_set_multicast_listfunction lan865x_send_packetfunction lan865x_hw_disablefunction lan865x_net_closefunction lan865x_hw_enablefunction lan865x_net_openfunction lan865x_probefunction lan865x_remove
Annotated Snippet
static const struct net_device_ops lan865x_netdev_ops = {
.ndo_open = lan865x_net_open,
.ndo_stop = lan865x_net_close,
.ndo_start_xmit = lan865x_send_packet,
.ndo_set_rx_mode = lan865x_set_multicast_list,
.ndo_set_mac_address = lan865x_set_mac_address,
.ndo_validate_addr = eth_validate_addr,
.ndo_eth_ioctl = phy_do_ioctl_running,
};
static int lan865x_probe(struct spi_device *spi)
{
struct net_device *netdev;
struct lan865x_priv *priv;
int ret;
netdev = alloc_etherdev(sizeof(struct lan865x_priv));
if (!netdev)
return -ENOMEM;
priv = netdev_priv(netdev);
priv->netdev = netdev;
priv->spi = spi;
spi_set_drvdata(spi, priv);
INIT_WORK(&priv->multicast_work, lan865x_multicast_work_handler);
priv->tc6 = oa_tc6_init(spi, netdev);
if (!priv->tc6) {
ret = -ENODEV;
goto free_netdev;
}
/* LAN865x Rev.B0/B1 configuration parameters from AN1760
* As per the Configuration Application Note AN1760 published in the
* link, https://www.microchip.com/en-us/application-notes/an1760
* Revision F (DS60001760G - June 2024), configure the MAC to set time
* stamping at the end of the Start of Frame Delimiter (SFD) and set the
* Timer Increment reg to 40 ns to be used as a 25 MHz internal clock.
*/
ret = oa_tc6_write_register(priv->tc6, LAN865X_REG_MAC_TSU_TIMER_INCR,
MAC_TSU_TIMER_INCR_COUNT_NANOSECONDS);
if (ret) {
dev_err(&spi->dev, "Failed to config TSU Timer Incr reg: %d\n",
ret);
goto oa_tc6_exit;
}
/* As per the point s3 in the below errata, SPI receive Ethernet frame
* transfer may halt when starting the next frame in the same data block
* (chunk) as the end of a previous frame. The RFA field should be
* configured to 01b or 10b for proper operation. In these modes, only
* one receive Ethernet frame will be placed in a single data block.
* When the RFA field is written to 01b, received frames will be forced
* to only start in the first word of the data block payload (SWO=0). As
* recommended, enable zero align receive frame feature for proper
* operation.
*
* https://ww1.microchip.com/downloads/aemDocuments/documents/AIS/ProductDocuments/Errata/LAN8650-1-Errata-80001075.pdf
*/
ret = oa_tc6_zero_align_receive_frame_enable(priv->tc6);
if (ret) {
dev_err(&spi->dev, "Failed to set ZARFE: %d\n", ret);
goto oa_tc6_exit;
}
/* Get the MAC address from the SPI device tree node */
if (device_get_ethdev_address(&spi->dev, netdev))
eth_hw_addr_random(netdev);
ret = lan865x_set_hw_macaddr(priv, netdev->dev_addr);
if (ret) {
dev_err(&spi->dev, "Failed to configure MAC: %d\n", ret);
goto oa_tc6_exit;
}
netdev->if_port = IF_PORT_10BASET;
netdev->irq = spi->irq;
netdev->netdev_ops = &lan865x_netdev_ops;
netdev->ethtool_ops = &lan865x_ethtool_ops;
ret = register_netdev(netdev);
if (ret) {
dev_err(&spi->dev, "Register netdev failed (ret = %d)", ret);
goto oa_tc6_exit;
}
return 0;
oa_tc6_exit:
oa_tc6_exit(priv->tc6);
Annotation
- Immediate include surface: `linux/module.h`, `linux/kernel.h`, `linux/phy.h`, `linux/oa_tc6.h`.
- Detected declarations: `struct lan865x_priv`, `function lan865x_set_hw_macaddr_low_bytes`, `function lan865x_set_hw_macaddr`, `function lan865x_set_mac_address`, `function get_address_bit`, `function lan865x_hash`, `function lan865x_set_specific_multicast_addr`, `function netdev_for_each_mc_addr`, `function lan865x_set_all_multicast_addr`, `function lan865x_clear_all_multicast_addr`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: pattern 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.