drivers/net/ethernet/intel/igc/igc_mac.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/intel/igc/igc_mac.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/intel/igc/igc_mac.c- Extension
.c- Size
- 24762 bytes
- Lines
- 872
- 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/pci.hlinux/delay.higc_mac.higc_hw.h
Detected Declarations
function igc_disable_pcie_masterfunction igc_init_rx_addrsfunction igc_set_fc_watermarksfunction igc_setup_linkfunction igc_force_mac_fcfunction igc_clear_hw_cntrs_basefunction igc_rar_setfunction igc_check_for_copper_linkfunction igc_config_collision_distfunction igc_config_fc_after_link_upfunction Registerfunction capabilityfunction igc_get_auto_rd_donefunction igc_get_speed_and_duplex_copperfunction igc_put_hw_semaphorefunction igc_enable_mng_pass_thrufunction igc_mta_setfunction igc_update_mc_addr_list
Annotated Snippet
if (hw->fc.requested_mode == igc_fc_full) {
hw->fc.current_mode = igc_fc_full;
hw_dbg("Flow Control = FULL.\n");
} else {
hw->fc.current_mode = igc_fc_rx_pause;
hw_dbg("Flow Control = RX PAUSE frames only.\n");
}
}
/* For receiving PAUSE frames ONLY.
*
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
* 0 | 1 | 1 | 1 | igc_fc_tx_pause
*/
else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
hw->fc.current_mode = igc_fc_tx_pause;
hw_dbg("Flow Control = TX PAUSE frames only.\n");
}
/* For transmitting PAUSE frames ONLY.
*
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
* 1 | 1 | 0 | 1 | igc_fc_rx_pause
*/
else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
!(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
hw->fc.current_mode = igc_fc_rx_pause;
hw_dbg("Flow Control = RX PAUSE frames only.\n");
}
/* Per the IEEE spec, at this point flow control should be
* disabled. However, we want to consider that we could
* be connected to a legacy switch that doesn't advertise
* desired flow control, but can be forced on the link
* partner. So if we advertised no flow control, that is
* what we will resolve to. If we advertised some kind of
* receive capability (Rx Pause Only or Full Flow Control)
* and the link partner advertised none, we will configure
* ourselves to enable Rx Flow Control only. We can do
* this safely for two reasons: If the link partner really
* didn't want flow control enabled, and we enable Rx, no
* harm done since we won't be receiving any PAUSE frames
* anyway. If the intent on the link partner was to have
* flow control enabled, then by us enabling RX only, we
* can at least receive pause frames and process them.
* This is a good idea because in most cases, since we are
* predominantly a server NIC, more times than not we will
* be asked to delay transmission of packets than asking
* our link partner to pause transmission of frames.
*/
else if ((hw->fc.requested_mode == igc_fc_none) ||
(hw->fc.requested_mode == igc_fc_tx_pause) ||
(hw->fc.strict_ieee)) {
hw->fc.current_mode = igc_fc_none;
hw_dbg("Flow Control = NONE.\n");
} else {
hw->fc.current_mode = igc_fc_rx_pause;
hw_dbg("Flow Control = RX PAUSE frames only.\n");
}
/* Now we need to do one last check... If we auto-
* negotiated to HALF DUPLEX, flow control should not be
* enabled per IEEE 802.3 spec.
*/
ret_val = hw->mac.ops.get_speed_and_duplex(hw, &speed, &duplex);
if (ret_val) {
hw_dbg("Error getting link speed and duplex\n");
goto out;
}
if (duplex == HALF_DUPLEX)
hw->fc.current_mode = igc_fc_none;
/* Now we call a subroutine to actually force the MAC
* controller to use the correct flow control settings.
*/
ret_val = igc_force_mac_fc(hw);
if (ret_val) {
hw_dbg("Error forcing flow control settings\n");
goto out;
}
out:
Annotation
- Immediate include surface: `linux/pci.h`, `linux/delay.h`, `igc_mac.h`, `igc_hw.h`.
- Detected declarations: `function igc_disable_pcie_master`, `function igc_init_rx_addrs`, `function igc_set_fc_watermarks`, `function igc_setup_link`, `function igc_force_mac_fc`, `function igc_clear_hw_cntrs_base`, `function igc_rar_set`, `function igc_check_for_copper_link`, `function igc_config_collision_dist`, `function igc_config_fc_after_link_up`.
- 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.