drivers/net/ethernet/atheros/alx/hw.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/atheros/alx/hw.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/atheros/alx/hw.c- Extension
.c- Size
- 32348 bytes
- Lines
- 1125
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/etherdevice.hlinux/delay.hlinux/pci.hlinux/mdio.hreg.hhw.h
Detected Declarations
function Copyrightfunction alx_wait_mdio_idlefunction alx_read_phy_corefunction alx_write_phy_corefunction __alx_read_phy_regfunction __alx_write_phy_regfunction __alx_read_phy_extfunction __alx_write_phy_extfunction __alx_read_phy_dbgfunction __alx_write_phy_dbgfunction alx_read_phy_regfunction alx_write_phy_regfunction alx_read_phy_extfunction alx_write_phy_extfunction alx_read_phy_dbgfunction alx_write_phy_dbgfunction alx_get_phy_configfunction alx_wait_regfunction alx_read_macaddrfunction alx_get_perm_macaddrfunction alx_set_macaddrfunction alx_reset_oscfunction alx_stop_macfunction alx_reset_macfunction alx_reset_phyfunction alx_reset_pciefunction alx_start_macfunction alx_cfg_mac_flowcontrolfunction alx_enable_aspmfunction ethadv_to_hw_cfgfunction alx_setup_speed_duplexfunction alx_post_phy_linkfunction alx_phy_configuredfunction alx_read_phy_linkfunction alx_clear_phy_intrfunction alx_disable_rssfunction alx_configure_basicfunction alx_mask_msixfunction alx_get_phy_infofunction alx_update_hw_stats
Annotated Snippet
if ((read & wait) == 0) {
if (val)
*val = read;
return true;
}
mdelay(1);
}
return false;
}
static bool alx_read_macaddr(struct alx_hw *hw, u8 *addr)
{
u32 mac0, mac1;
mac0 = alx_read_mem32(hw, ALX_STAD0);
mac1 = alx_read_mem32(hw, ALX_STAD1);
/* addr should be big-endian */
put_unaligned(cpu_to_be32(mac0), (__be32 *)(addr + 2));
put_unaligned(cpu_to_be16(mac1), (__be16 *)addr);
return is_valid_ether_addr(addr);
}
int alx_get_perm_macaddr(struct alx_hw *hw, u8 *addr)
{
u32 val;
/* try to get it from register first */
if (alx_read_macaddr(hw, addr))
return 0;
/* try to load from efuse */
if (!alx_wait_reg(hw, ALX_SLD, ALX_SLD_STAT | ALX_SLD_START, &val))
return -EIO;
alx_write_mem32(hw, ALX_SLD, val | ALX_SLD_START);
if (!alx_wait_reg(hw, ALX_SLD, ALX_SLD_START, NULL))
return -EIO;
if (alx_read_macaddr(hw, addr))
return 0;
/* try to load from flash/eeprom (if present) */
val = alx_read_mem32(hw, ALX_EFLD);
if (val & (ALX_EFLD_F_EXIST | ALX_EFLD_E_EXIST)) {
if (!alx_wait_reg(hw, ALX_EFLD,
ALX_EFLD_STAT | ALX_EFLD_START, &val))
return -EIO;
alx_write_mem32(hw, ALX_EFLD, val | ALX_EFLD_START);
if (!alx_wait_reg(hw, ALX_EFLD, ALX_EFLD_START, NULL))
return -EIO;
if (alx_read_macaddr(hw, addr))
return 0;
}
return -EIO;
}
void alx_set_macaddr(struct alx_hw *hw, const u8 *addr)
{
u32 val;
/* for example: 00-0B-6A-F6-00-DC * STAD0=6AF600DC, STAD1=000B */
val = be32_to_cpu(get_unaligned((__be32 *)(addr + 2)));
alx_write_mem32(hw, ALX_STAD0, val);
val = be16_to_cpu(get_unaligned((__be16 *)addr));
alx_write_mem32(hw, ALX_STAD1, val);
}
static void alx_reset_osc(struct alx_hw *hw, u8 rev)
{
u32 val, val2;
/* clear Internal OSC settings, switching OSC by hw itself */
val = alx_read_mem32(hw, ALX_MISC3);
alx_write_mem32(hw, ALX_MISC3,
(val & ~ALX_MISC3_25M_BY_SW) |
ALX_MISC3_25M_NOTO_INTNL);
/* 25M clk from chipset may be unstable 1s after de-assert of
* PERST, driver need re-calibrate before enter Sleep for WoL
*/
val = alx_read_mem32(hw, ALX_MISC);
if (rev >= ALX_REV_B0) {
/* restore over current protection def-val,
* this val could be reset by MAC-RST
*/
ALX_SET_FIELD(val, ALX_MISC_PSW_OCP, ALX_MISC_PSW_OCP_DEF);
/* a 0->1 change will update the internal val of osc */
val &= ~ALX_MISC_INTNLOSC_OPEN;
Annotation
- Immediate include surface: `linux/etherdevice.h`, `linux/delay.h`, `linux/pci.h`, `linux/mdio.h`, `reg.h`, `hw.h`.
- Detected declarations: `function Copyright`, `function alx_wait_mdio_idle`, `function alx_read_phy_core`, `function alx_write_phy_core`, `function __alx_read_phy_reg`, `function __alx_write_phy_reg`, `function __alx_read_phy_ext`, `function __alx_write_phy_ext`, `function __alx_read_phy_dbg`, `function __alx_write_phy_dbg`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.