Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/igc/if_igc.c
Show First 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | |||||
static uint64_t igc_if_get_counter(if_ctx_t, ift_counter); | static uint64_t igc_if_get_counter(if_ctx_t, ift_counter); | ||||
static void igc_if_init(if_ctx_t ctx); | static void igc_if_init(if_ctx_t ctx); | ||||
static void igc_if_stop(if_ctx_t ctx); | static void igc_if_stop(if_ctx_t ctx); | ||||
static void igc_if_media_status(if_ctx_t, struct ifmediareq *); | static void igc_if_media_status(if_ctx_t, struct ifmediareq *); | ||||
static int igc_if_media_change(if_ctx_t ctx); | static int igc_if_media_change(if_ctx_t ctx); | ||||
static int igc_if_mtu_set(if_ctx_t ctx, uint32_t mtu); | static int igc_if_mtu_set(if_ctx_t ctx, uint32_t mtu); | ||||
static void igc_if_timer(if_ctx_t ctx, uint16_t qid); | static void igc_if_timer(if_ctx_t ctx, uint16_t qid); | ||||
static void igc_if_vlan_register(if_ctx_t ctx, u16 vtag); | |||||
static void igc_if_vlan_unregister(if_ctx_t ctx, u16 vtag); | |||||
static void igc_if_watchdog_reset(if_ctx_t ctx); | static void igc_if_watchdog_reset(if_ctx_t ctx); | ||||
static bool igc_if_needs_restart(if_ctx_t ctx, enum iflib_restart_event event); | static bool igc_if_needs_restart(if_ctx_t ctx, enum iflib_restart_event event); | ||||
static void igc_identify_hardware(if_ctx_t ctx); | static void igc_identify_hardware(if_ctx_t ctx); | ||||
static int igc_allocate_pci_resources(if_ctx_t ctx); | static int igc_allocate_pci_resources(if_ctx_t ctx); | ||||
static void igc_free_pci_resources(if_ctx_t ctx); | static void igc_free_pci_resources(if_ctx_t ctx); | ||||
static void igc_reset(if_ctx_t ctx); | static void igc_reset(if_ctx_t ctx); | ||||
static int igc_setup_interface(if_ctx_t ctx); | static int igc_setup_interface(if_ctx_t ctx); | ||||
static int igc_setup_msix(if_ctx_t ctx); | static int igc_setup_msix(if_ctx_t ctx); | ||||
static void igc_initialize_transmit_unit(if_ctx_t ctx); | static void igc_initialize_transmit_unit(if_ctx_t ctx); | ||||
static void igc_initialize_receive_unit(if_ctx_t ctx); | static void igc_initialize_receive_unit(if_ctx_t ctx); | ||||
static void igc_if_intr_enable(if_ctx_t ctx); | static void igc_if_intr_enable(if_ctx_t ctx); | ||||
static void igc_if_intr_disable(if_ctx_t ctx); | static void igc_if_intr_disable(if_ctx_t ctx); | ||||
static int igc_if_rx_queue_intr_enable(if_ctx_t ctx, uint16_t rxqid); | static int igc_if_rx_queue_intr_enable(if_ctx_t ctx, uint16_t rxqid); | ||||
static int igc_if_tx_queue_intr_enable(if_ctx_t ctx, uint16_t txqid); | static int igc_if_tx_queue_intr_enable(if_ctx_t ctx, uint16_t txqid); | ||||
static void igc_if_multi_set(if_ctx_t ctx); | static void igc_if_multi_set(if_ctx_t ctx); | ||||
static void igc_if_update_admin_status(if_ctx_t ctx); | static void igc_if_update_admin_status(if_ctx_t ctx); | ||||
static void igc_if_debug(if_ctx_t ctx); | static void igc_if_debug(if_ctx_t ctx); | ||||
static void igc_update_stats_counters(struct igc_adapter *); | static void igc_update_stats_counters(struct igc_adapter *); | ||||
static void igc_add_hw_stats(struct igc_adapter *adapter); | static void igc_add_hw_stats(struct igc_adapter *adapter); | ||||
static int igc_if_set_promisc(if_ctx_t ctx, int flags); | static int igc_if_set_promisc(if_ctx_t ctx, int flags); | ||||
static void igc_setup_vlan_hw_support(struct igc_adapter *); | static void igc_setup_vlan_hw_support(if_ctx_t ctx); | ||||
static int igc_sysctl_nvm_info(SYSCTL_HANDLER_ARGS); | static int igc_sysctl_nvm_info(SYSCTL_HANDLER_ARGS); | ||||
static void igc_print_nvm_info(struct igc_adapter *); | static void igc_print_nvm_info(struct igc_adapter *); | ||||
static int igc_sysctl_debug_info(SYSCTL_HANDLER_ARGS); | static int igc_sysctl_debug_info(SYSCTL_HANDLER_ARGS); | ||||
static int igc_get_rs(SYSCTL_HANDLER_ARGS); | static int igc_get_rs(SYSCTL_HANDLER_ARGS); | ||||
static void igc_print_debug_info(struct igc_adapter *); | static void igc_print_debug_info(struct igc_adapter *); | ||||
static int igc_is_valid_ether_addr(u8 *); | static int igc_is_valid_ether_addr(u8 *); | ||||
static int igc_sysctl_int_delay(SYSCTL_HANDLER_ARGS); | static int igc_sysctl_int_delay(SYSCTL_HANDLER_ARGS); | ||||
static void igc_add_int_delay_sysctl(struct igc_adapter *, const char *, | static void igc_add_int_delay_sysctl(struct igc_adapter *, const char *, | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | static device_method_t igc_if_methods[] = { | ||||
DEVMETHOD(ifdi_update_admin_status, igc_if_update_admin_status), | DEVMETHOD(ifdi_update_admin_status, igc_if_update_admin_status), | ||||
DEVMETHOD(ifdi_multi_set, igc_if_multi_set), | DEVMETHOD(ifdi_multi_set, igc_if_multi_set), | ||||
DEVMETHOD(ifdi_media_status, igc_if_media_status), | DEVMETHOD(ifdi_media_status, igc_if_media_status), | ||||
DEVMETHOD(ifdi_media_change, igc_if_media_change), | DEVMETHOD(ifdi_media_change, igc_if_media_change), | ||||
DEVMETHOD(ifdi_mtu_set, igc_if_mtu_set), | DEVMETHOD(ifdi_mtu_set, igc_if_mtu_set), | ||||
DEVMETHOD(ifdi_promisc_set, igc_if_set_promisc), | DEVMETHOD(ifdi_promisc_set, igc_if_set_promisc), | ||||
DEVMETHOD(ifdi_timer, igc_if_timer), | DEVMETHOD(ifdi_timer, igc_if_timer), | ||||
DEVMETHOD(ifdi_watchdog_reset, igc_if_watchdog_reset), | DEVMETHOD(ifdi_watchdog_reset, igc_if_watchdog_reset), | ||||
DEVMETHOD(ifdi_vlan_register, igc_if_vlan_register), | |||||
DEVMETHOD(ifdi_vlan_unregister, igc_if_vlan_unregister), | |||||
DEVMETHOD(ifdi_get_counter, igc_if_get_counter), | DEVMETHOD(ifdi_get_counter, igc_if_get_counter), | ||||
DEVMETHOD(ifdi_rx_queue_intr_enable, igc_if_rx_queue_intr_enable), | DEVMETHOD(ifdi_rx_queue_intr_enable, igc_if_rx_queue_intr_enable), | ||||
DEVMETHOD(ifdi_tx_queue_intr_enable, igc_if_tx_queue_intr_enable), | DEVMETHOD(ifdi_tx_queue_intr_enable, igc_if_tx_queue_intr_enable), | ||||
DEVMETHOD(ifdi_debug, igc_if_debug), | DEVMETHOD(ifdi_debug, igc_if_debug), | ||||
DEVMETHOD(ifdi_needs_restart, igc_if_needs_restart), | DEVMETHOD(ifdi_needs_restart, igc_if_needs_restart), | ||||
DEVMETHOD_END | DEVMETHOD_END | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 224 Lines • ▼ Show 20 Lines | igc_set_num_queues(if_ctx_t ctx) | ||||
maxqueues = 4; | maxqueues = 4; | ||||
return (maxqueues); | return (maxqueues); | ||||
} | } | ||||
#define IGC_CAPS \ | #define IGC_CAPS \ | ||||
IFCAP_HWCSUM | IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \ | IFCAP_HWCSUM | IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \ | ||||
IFCAP_VLAN_HWCSUM | IFCAP_WOL | IFCAP_VLAN_HWFILTER | IFCAP_TSO4 | \ | IFCAP_VLAN_HWCSUM | IFCAP_WOL | IFCAP_TSO4 | IFCAP_LRO | \ | ||||
IFCAP_LRO | IFCAP_VLAN_HWTSO | IFCAP_JUMBO_MTU | IFCAP_HWCSUM_IPV6 |\ | IFCAP_VLAN_HWTSO | IFCAP_JUMBO_MTU | IFCAP_HWCSUM_IPV6 | IFCAP_TSO6 | ||||
IFCAP_TSO6 | |||||
/********************************************************************* | /********************************************************************* | ||||
* Device initialization routine | * Device initialization routine | ||||
* | * | ||||
* The attach entry point is called when the driver is being loaded. | * The attach entry point is called when the driver is being loaded. | ||||
* This routine identifies the type of hardware, allocates all resources | * This routine identifies the type of hardware, allocates all resources | ||||
* and initializes the hardware. | * and initializes the hardware. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 384 Lines • ▼ Show 20 Lines | igc_if_init(if_ctx_t ctx) | ||||
igc_initialize_transmit_unit(ctx); | igc_initialize_transmit_unit(ctx); | ||||
/* Setup Multicast table */ | /* Setup Multicast table */ | ||||
igc_if_multi_set(ctx); | igc_if_multi_set(ctx); | ||||
adapter->rx_mbuf_sz = iflib_get_rx_mbuf_sz(ctx); | adapter->rx_mbuf_sz = iflib_get_rx_mbuf_sz(ctx); | ||||
igc_initialize_receive_unit(ctx); | igc_initialize_receive_unit(ctx); | ||||
/* Use real VLAN Filter support? */ | /* Set up VLAN support */ | ||||
if (if_getcapenable(ifp) & IFCAP_VLAN_HWTAGGING) { | igc_setup_vlan_hw_support(ctx); | ||||
if (if_getcapenable(ifp) & IFCAP_VLAN_HWFILTER) | |||||
/* Use real VLAN Filter support */ | |||||
igc_setup_vlan_hw_support(adapter); | |||||
else { | |||||
u32 ctrl; | |||||
ctrl = IGC_READ_REG(&adapter->hw, IGC_CTRL); | |||||
ctrl |= IGC_CTRL_VME; | |||||
IGC_WRITE_REG(&adapter->hw, IGC_CTRL, ctrl); | |||||
} | |||||
} | |||||
/* Don't lose promiscuous settings */ | /* Don't lose promiscuous settings */ | ||||
igc_if_set_promisc(ctx, if_getflags(ifp)); | igc_if_set_promisc(ctx, if_getflags(ifp)); | ||||
igc_clear_hw_cntrs_base_generic(&adapter->hw); | igc_clear_hw_cntrs_base_generic(&adapter->hw); | ||||
if (adapter->intr_type == IFLIB_INTR_MSIX) /* Set up queue routing */ | if (adapter->intr_type == IFLIB_INTR_MSIX) /* Set up queue routing */ | ||||
igc_configure_queues(adapter); | igc_configure_queues(adapter); | ||||
▲ Show 20 Lines • Show All 1,266 Lines • ▼ Show 20 Lines | #endif | ||||
/* Write out the settings */ | /* Write out the settings */ | ||||
IGC_WRITE_REG(hw, IGC_RCTL, rctl); | IGC_WRITE_REG(hw, IGC_RCTL, rctl); | ||||
return; | return; | ||||
} | } | ||||
static void | static void | ||||
igc_if_vlan_register(if_ctx_t ctx, u16 vtag) | igc_setup_vlan_hw_support(if_ctx_t ctx) | ||||
{ | { | ||||
struct igc_adapter *adapter = iflib_get_softc(ctx); | struct igc_adapter *adapter = iflib_get_softc(ctx); | ||||
u32 index, bit; | |||||
index = (vtag >> 5) & 0x7F; | |||||
bit = vtag & 0x1F; | |||||
adapter->shadow_vfta[index] |= (1 << bit); | |||||
++adapter->num_vlans; | |||||
} | |||||
static void | |||||
igc_if_vlan_unregister(if_ctx_t ctx, u16 vtag) | |||||
{ | |||||
struct igc_adapter *adapter = iflib_get_softc(ctx); | |||||
u32 index, bit; | |||||
index = (vtag >> 5) & 0x7F; | |||||
bit = vtag & 0x1F; | |||||
adapter->shadow_vfta[index] &= ~(1 << bit); | |||||
--adapter->num_vlans; | |||||
} | |||||
static void | |||||
igc_setup_vlan_hw_support(struct igc_adapter *adapter) | |||||
{ | |||||
struct igc_hw *hw = &adapter->hw; | struct igc_hw *hw = &adapter->hw; | ||||
struct ifnet *ifp = iflib_get_ifp(ctx); | |||||
u32 reg; | u32 reg; | ||||
/* | /* igc hardware doesn't seem to implement VFTA for HWFILTER */ | ||||
* We get here thru init_locked, meaning | |||||
* a soft reset, this has already cleared | |||||
* the VFTA and other state, so if there | |||||
* have been no vlan's registered do nothing. | |||||
*/ | |||||
if (adapter->num_vlans == 0) | |||||
return; | |||||
/* | if (if_getcapenable(ifp) & IFCAP_VLAN_HWTAGGING && | ||||
* A soft reset zero's out the VFTA, so | !igc_disable_crc_stripping) { | ||||
* we need to repopulate it now. | |||||
*/ | |||||
for (int i = 0; i < IGC_VFTA_SIZE; i++) | |||||
if (adapter->shadow_vfta[i] != 0) | |||||
IGC_WRITE_REG_ARRAY(hw, IGC_VFTA, | |||||
i, adapter->shadow_vfta[i]); | |||||
reg = IGC_READ_REG(hw, IGC_CTRL); | reg = IGC_READ_REG(hw, IGC_CTRL); | ||||
reg |= IGC_CTRL_VME; | reg |= IGC_CTRL_VME; | ||||
IGC_WRITE_REG(hw, IGC_CTRL, reg); | IGC_WRITE_REG(hw, IGC_CTRL, reg); | ||||
} else { | |||||
/* Enable the Filter Table */ | reg = IGC_READ_REG(hw, IGC_CTRL); | ||||
reg = IGC_READ_REG(hw, IGC_RCTL); | reg &= ~IGC_CTRL_VME; | ||||
reg &= ~IGC_RCTL_CFIEN; | IGC_WRITE_REG(hw, IGC_CTRL, reg); | ||||
reg |= IGC_RCTL_VFE; | |||||
IGC_WRITE_REG(hw, IGC_RCTL, reg); | |||||
} | } | ||||
} | |||||
static void | static void | ||||
igc_if_intr_enable(if_ctx_t ctx) | igc_if_intr_enable(if_ctx_t ctx) | ||||
{ | { | ||||
struct igc_adapter *adapter = iflib_get_softc(ctx); | struct igc_adapter *adapter = iflib_get_softc(ctx); | ||||
struct igc_hw *hw = &adapter->hw; | struct igc_hw *hw = &adapter->hw; | ||||
u32 mask; | u32 mask; | ||||
▲ Show 20 Lines • Show All 258 Lines • ▼ Show 20 Lines | |||||
* | * | ||||
* @returns true if iflib needs to reinit the interface | * @returns true if iflib needs to reinit the interface | ||||
*/ | */ | ||||
static bool | static bool | ||||
igc_if_needs_restart(if_ctx_t ctx __unused, enum iflib_restart_event event) | igc_if_needs_restart(if_ctx_t ctx __unused, enum iflib_restart_event event) | ||||
{ | { | ||||
switch (event) { | switch (event) { | ||||
case IFLIB_RESTART_VLAN_CONFIG: | case IFLIB_RESTART_VLAN_CONFIG: | ||||
return (false); | |||||
default: | default: | ||||
return (true); | return (true); | ||||
} | } | ||||
} | } | ||||
/* Export a single 32-bit register via a read-only sysctl. */ | /* Export a single 32-bit register via a read-only sysctl. */ | ||||
static int | static int | ||||
igc_sysctl_reg_handler(SYSCTL_HANDLER_ARGS) | igc_sysctl_reg_handler(SYSCTL_HANDLER_ARGS) | ||||
▲ Show 20 Lines • Show All 505 Lines • Show Last 20 Lines |