Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/ixgbe/if_ix.c
Show First 20 Lines • Show All 114 Lines • ▼ Show 20 Lines | |||||
static int ixgbe_if_detach(if_ctx_t ctx); | static int ixgbe_if_detach(if_ctx_t ctx); | ||||
static int ixgbe_if_shutdown(if_ctx_t ctx); | static int ixgbe_if_shutdown(if_ctx_t ctx); | ||||
static int ixgbe_if_suspend(if_ctx_t ctx); | static int ixgbe_if_suspend(if_ctx_t ctx); | ||||
static int ixgbe_if_resume(if_ctx_t ctx); | static int ixgbe_if_resume(if_ctx_t ctx); | ||||
static void ixgbe_if_stop(if_ctx_t ctx); | static void ixgbe_if_stop(if_ctx_t ctx); | ||||
void ixgbe_if_enable_intr(if_ctx_t ctx); | void ixgbe_if_enable_intr(if_ctx_t ctx); | ||||
static void ixgbe_if_disable_intr(if_ctx_t ctx); | static void ixgbe_if_disable_intr(if_ctx_t ctx); | ||||
static void ixgbe_link_intr_enable(if_ctx_t ctx); | |||||
static int ixgbe_if_rx_queue_intr_enable(if_ctx_t ctx, uint16_t qid); | static int ixgbe_if_rx_queue_intr_enable(if_ctx_t ctx, uint16_t qid); | ||||
static void ixgbe_if_media_status(if_ctx_t ctx, struct ifmediareq * ifmr); | static void ixgbe_if_media_status(if_ctx_t ctx, struct ifmediareq * ifmr); | ||||
static int ixgbe_if_media_change(if_ctx_t ctx); | static int ixgbe_if_media_change(if_ctx_t ctx); | ||||
static int ixgbe_if_msix_intr_assign(if_ctx_t, int); | static int ixgbe_if_msix_intr_assign(if_ctx_t, int); | ||||
static int ixgbe_if_mtu_set(if_ctx_t ctx, uint32_t mtu); | static int ixgbe_if_mtu_set(if_ctx_t ctx, uint32_t mtu); | ||||
static void ixgbe_if_crcstrip_set(if_ctx_t ctx, int onoff, int strip); | static void ixgbe_if_crcstrip_set(if_ctx_t ctx, int onoff, int strip); | ||||
static void ixgbe_if_multi_set(if_ctx_t ctx); | static void ixgbe_if_multi_set(if_ctx_t ctx); | ||||
static int ixgbe_if_promisc_set(if_ctx_t ctx, int flags); | static int ixgbe_if_promisc_set(if_ctx_t ctx, int flags); | ||||
Show All 37 Lines | |||||
static void ixgbe_initialize_receive_units(if_ctx_t ctx); | static void ixgbe_initialize_receive_units(if_ctx_t ctx); | ||||
static void ixgbe_initialize_transmit_units(if_ctx_t ctx); | static void ixgbe_initialize_transmit_units(if_ctx_t ctx); | ||||
static int ixgbe_setup_interface(if_ctx_t ctx); | static int ixgbe_setup_interface(if_ctx_t ctx); | ||||
static void ixgbe_init_device_features(struct adapter *adapter); | static void ixgbe_init_device_features(struct adapter *adapter); | ||||
static void ixgbe_check_fan_failure(struct adapter *, u32, bool); | static void ixgbe_check_fan_failure(struct adapter *, u32, bool); | ||||
static void ixgbe_add_media_types(if_ctx_t ctx); | static void ixgbe_add_media_types(if_ctx_t ctx); | ||||
static void ixgbe_update_stats_counters(struct adapter *adapter); | static void ixgbe_update_stats_counters(struct adapter *adapter); | ||||
static void ixgbe_config_link(struct adapter *adapter); | static void ixgbe_config_link(if_ctx_t ctx); | ||||
static void ixgbe_get_slot_info(struct adapter *); | static void ixgbe_get_slot_info(struct adapter *); | ||||
static void ixgbe_check_wol_support(struct adapter *adapter); | static void ixgbe_check_wol_support(struct adapter *adapter); | ||||
static void ixgbe_enable_rx_drop(struct adapter *); | static void ixgbe_enable_rx_drop(struct adapter *); | ||||
static void ixgbe_disable_rx_drop(struct adapter *); | static void ixgbe_disable_rx_drop(struct adapter *); | ||||
static void ixgbe_add_hw_stats(struct adapter *adapter); | static void ixgbe_add_hw_stats(struct adapter *adapter); | ||||
static int ixgbe_set_flowcntl(struct adapter *, int); | static int ixgbe_set_flowcntl(struct adapter *, int); | ||||
static int ixgbe_set_advertise(struct adapter *, int); | static int ixgbe_set_advertise(struct adapter *, int); | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | static device_method_t ixgbe_if_methods[] = { | ||||
DEVMETHOD(ifdi_shutdown, ixgbe_if_shutdown), | DEVMETHOD(ifdi_shutdown, ixgbe_if_shutdown), | ||||
DEVMETHOD(ifdi_suspend, ixgbe_if_suspend), | DEVMETHOD(ifdi_suspend, ixgbe_if_suspend), | ||||
DEVMETHOD(ifdi_resume, ixgbe_if_resume), | DEVMETHOD(ifdi_resume, ixgbe_if_resume), | ||||
DEVMETHOD(ifdi_init, ixgbe_if_init), | DEVMETHOD(ifdi_init, ixgbe_if_init), | ||||
DEVMETHOD(ifdi_stop, ixgbe_if_stop), | DEVMETHOD(ifdi_stop, ixgbe_if_stop), | ||||
DEVMETHOD(ifdi_msix_intr_assign, ixgbe_if_msix_intr_assign), | DEVMETHOD(ifdi_msix_intr_assign, ixgbe_if_msix_intr_assign), | ||||
DEVMETHOD(ifdi_intr_enable, ixgbe_if_enable_intr), | DEVMETHOD(ifdi_intr_enable, ixgbe_if_enable_intr), | ||||
DEVMETHOD(ifdi_intr_disable, ixgbe_if_disable_intr), | DEVMETHOD(ifdi_intr_disable, ixgbe_if_disable_intr), | ||||
DEVMETHOD(ifdi_link_intr_enable, ixgbe_link_intr_enable), | |||||
DEVMETHOD(ifdi_tx_queue_intr_enable, ixgbe_if_rx_queue_intr_enable), | DEVMETHOD(ifdi_tx_queue_intr_enable, ixgbe_if_rx_queue_intr_enable), | ||||
DEVMETHOD(ifdi_rx_queue_intr_enable, ixgbe_if_rx_queue_intr_enable), | DEVMETHOD(ifdi_rx_queue_intr_enable, ixgbe_if_rx_queue_intr_enable), | ||||
DEVMETHOD(ifdi_tx_queues_alloc, ixgbe_if_tx_queues_alloc), | DEVMETHOD(ifdi_tx_queues_alloc, ixgbe_if_tx_queues_alloc), | ||||
DEVMETHOD(ifdi_rx_queues_alloc, ixgbe_if_rx_queues_alloc), | DEVMETHOD(ifdi_rx_queues_alloc, ixgbe_if_rx_queues_alloc), | ||||
DEVMETHOD(ifdi_queues_free, ixgbe_if_queues_free), | DEVMETHOD(ifdi_queues_free, ixgbe_if_queues_free), | ||||
DEVMETHOD(ifdi_update_admin_status, ixgbe_if_update_admin_status), | DEVMETHOD(ifdi_update_admin_status, ixgbe_if_update_admin_status), | ||||
DEVMETHOD(ifdi_multi_set, ixgbe_if_multi_set), | DEVMETHOD(ifdi_multi_set, ixgbe_if_multi_set), | ||||
DEVMETHOD(ifdi_mtu_set, ixgbe_if_mtu_set), | DEVMETHOD(ifdi_mtu_set, ixgbe_if_mtu_set), | ||||
▲ Show 20 Lines • Show All 176 Lines • ▼ Show 20 Lines | for (i = 0, que = adapter->tx_queues; i < ntxqsets; i++, que++) { | ||||
txr->total_packets = 0; | txr->total_packets = 0; | ||||
/* Set the rate at which we sample packets */ | /* Set the rate at which we sample packets */ | ||||
if (adapter->feat_en & IXGBE_FEATURE_FDIR) | if (adapter->feat_en & IXGBE_FEATURE_FDIR) | ||||
txr->atr_sample = atr_sample_rate; | txr->atr_sample = atr_sample_rate; | ||||
} | } | ||||
iflib_config_gtask_init(ctx, &adapter->mod_task, ixgbe_handle_mod, | |||||
"mod_task"); | |||||
iflib_config_gtask_init(ctx, &adapter->msf_task, ixgbe_handle_msf, | |||||
"msf_task"); | |||||
iflib_config_gtask_init(ctx, &adapter->phy_task, ixgbe_handle_phy, | |||||
"phy_task"); | |||||
if (adapter->feat_cap & IXGBE_FEATURE_SRIOV) | |||||
iflib_config_gtask_init(ctx, &adapter->mbx_task, | |||||
ixgbe_handle_mbx, "mbx_task"); | |||||
if (adapter->feat_en & IXGBE_FEATURE_FDIR) | |||||
iflib_config_gtask_init(ctx, &adapter->fdir_task, | |||||
ixgbe_reinit_fdir, "fdir_task"); | |||||
device_printf(iflib_get_dev(ctx), "allocated for %d queues\n", | device_printf(iflib_get_dev(ctx), "allocated for %d queues\n", | ||||
adapter->num_tx_queues); | adapter->num_tx_queues); | ||||
return (0); | return (0); | ||||
fail: | fail: | ||||
ixgbe_if_queues_free(ctx); | ixgbe_if_queues_free(ctx); | ||||
▲ Show 20 Lines • Show All 887 Lines • ▼ Show 20 Lines | default: | ||||
return (FALSE); | return (FALSE); | ||||
} | } | ||||
} /* ixgbe_is_sfp */ | } /* ixgbe_is_sfp */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_config_link | * ixgbe_config_link | ||||
************************************************************************/ | ************************************************************************/ | ||||
static void | static void | ||||
ixgbe_config_link(struct adapter *adapter) | ixgbe_config_link(if_ctx_t ctx) | ||||
{ | { | ||||
struct adapter *adapter = iflib_get_softc(ctx); | |||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &adapter->hw; | ||||
u32 autoneg, err = 0; | u32 autoneg, err = 0; | ||||
bool sfp, negotiate; | bool sfp, negotiate; | ||||
sfp = ixgbe_is_sfp(hw); | sfp = ixgbe_is_sfp(hw); | ||||
if (sfp) { | if (sfp) { | ||||
GROUPTASK_ENQUEUE(&adapter->mod_task); | adapter->task_requests |= IXGBE_REQUEST_TASK_MOD; | ||||
iflib_admin_intr_deferred(ctx); | |||||
} else { | } else { | ||||
if (hw->mac.ops.check_link) | if (hw->mac.ops.check_link) | ||||
err = ixgbe_check_link(hw, &adapter->link_speed, | err = ixgbe_check_link(hw, &adapter->link_speed, | ||||
&adapter->link_up, FALSE); | &adapter->link_up, FALSE); | ||||
if (err) | if (err) | ||||
return; | return; | ||||
autoneg = hw->phy.autoneg_advertised; | autoneg = hw->phy.autoneg_advertised; | ||||
if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) | if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) | ||||
err = hw->mac.ops.get_link_capabilities(hw, &autoneg, | err = hw->mac.ops.get_link_capabilities(hw, &autoneg, | ||||
&negotiate); | &negotiate); | ||||
if (err) | if (err) | ||||
return; | return; | ||||
if (hw->mac.ops.setup_link) | if (hw->mac.ops.setup_link) | ||||
err = hw->mac.ops.setup_link(hw, autoneg, | err = hw->mac.ops.setup_link(hw, autoneg, | ||||
adapter->link_up); | adapter->link_up); | ||||
} | } | ||||
} /* ixgbe_config_link */ | } /* ixgbe_config_link */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_update_stats_counters - Update board statistics counters. | * ixgbe_update_stats_counters - Update board statistics counters. | ||||
************************************************************************/ | ************************************************************************/ | ||||
static void | static void | ||||
ixgbe_update_stats_counters(struct adapter *adapter) | ixgbe_update_stats_counters(struct adapter *adapter) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 691 Lines • ▼ Show 20 Lines | |||||
ixgbe_if_media_status(if_ctx_t ctx, struct ifmediareq * ifmr) | ixgbe_if_media_status(if_ctx_t ctx, struct ifmediareq * ifmr) | ||||
{ | { | ||||
struct adapter *adapter = iflib_get_softc(ctx); | struct adapter *adapter = iflib_get_softc(ctx); | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &adapter->hw; | ||||
int layer; | int layer; | ||||
INIT_DEBUGOUT("ixgbe_if_media_status: begin"); | INIT_DEBUGOUT("ixgbe_if_media_status: begin"); | ||||
iflib_admin_intr_deferred(ctx); | |||||
ifmr->ifm_status = IFM_AVALID; | ifmr->ifm_status = IFM_AVALID; | ||||
ifmr->ifm_active = IFM_ETHER; | ifmr->ifm_active = IFM_ETHER; | ||||
if (!adapter->link_active) | if (!adapter->link_active) | ||||
return; | return; | ||||
ifmr->ifm_status |= IFM_ACTIVE; | ifmr->ifm_status |= IFM_ACTIVE; | ||||
layer = adapter->phy_layer; | layer = adapter->phy_layer; | ||||
▲ Show 20 Lines • Show All 272 Lines • ▼ Show 20 Lines | ixgbe_msix_link(void *arg) | ||||
/* Be sure the queue bits are not cleared */ | /* Be sure the queue bits are not cleared */ | ||||
eicr &= ~IXGBE_EICR_RTX_QUEUE; | eicr &= ~IXGBE_EICR_RTX_QUEUE; | ||||
/* Clear interrupt with write */ | /* Clear interrupt with write */ | ||||
IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr); | IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr); | ||||
/* Link status change */ | /* Link status change */ | ||||
if (eicr & IXGBE_EICR_LSC) { | if (eicr & IXGBE_EICR_LSC) { | ||||
IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC); | IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC); | ||||
iflib_admin_intr_deferred(adapter->ctx); | adapter->task_requests |= IXGBE_REQUEST_TASK_LSC; | ||||
} | } | ||||
if (adapter->hw.mac.type != ixgbe_mac_82598EB) { | if (adapter->hw.mac.type != ixgbe_mac_82598EB) { | ||||
if ((adapter->feat_en & IXGBE_FEATURE_FDIR) && | if ((adapter->feat_en & IXGBE_FEATURE_FDIR) && | ||||
(eicr & IXGBE_EICR_FLOW_DIR)) { | (eicr & IXGBE_EICR_FLOW_DIR)) { | ||||
/* This is probably overkill :) */ | /* This is probably overkill :) */ | ||||
if (!atomic_cmpset_int(&adapter->fdir_reinit, 0, 1)) | if (!atomic_cmpset_int(&adapter->fdir_reinit, 0, 1)) | ||||
return (FILTER_HANDLED); | return (FILTER_HANDLED); | ||||
/* Disable the interrupt */ | /* Disable the interrupt */ | ||||
IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EICR_FLOW_DIR); | IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EICR_FLOW_DIR); | ||||
GROUPTASK_ENQUEUE(&adapter->fdir_task); | adapter->task_requests |= IXGBE_REQUEST_TASK_FDIR; | ||||
} else | } else | ||||
if (eicr & IXGBE_EICR_ECC) { | if (eicr & IXGBE_EICR_ECC) { | ||||
device_printf(iflib_get_dev(adapter->ctx), | device_printf(iflib_get_dev(adapter->ctx), | ||||
"\nCRITICAL: ECC ERROR!! Please Reboot!!\n"); | "\nCRITICAL: ECC ERROR!! Please Reboot!!\n"); | ||||
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC); | IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC); | ||||
} | } | ||||
/* Check for over temp condition */ | /* Check for over temp condition */ | ||||
Show All 27 Lines | if (adapter->feat_en & IXGBE_FEATURE_TEMP_SENSOR) { | ||||
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_TS); | IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_TS); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
/* Check for VF message */ | /* Check for VF message */ | ||||
if ((adapter->feat_en & IXGBE_FEATURE_SRIOV) && | if ((adapter->feat_en & IXGBE_FEATURE_SRIOV) && | ||||
(eicr & IXGBE_EICR_MAILBOX)) | (eicr & IXGBE_EICR_MAILBOX)) | ||||
GROUPTASK_ENQUEUE(&adapter->mbx_task); | adapter->task_requests |= IXGBE_REQUEST_TASK_MBX; | ||||
} | } | ||||
if (ixgbe_is_sfp(hw)) { | if (ixgbe_is_sfp(hw)) { | ||||
/* Pluggable optics-related interrupt */ | /* Pluggable optics-related interrupt */ | ||||
if (hw->mac.type >= ixgbe_mac_X540) | if (hw->mac.type >= ixgbe_mac_X540) | ||||
eicr_mask = IXGBE_EICR_GPI_SDP0_X540; | eicr_mask = IXGBE_EICR_GPI_SDP0_X540; | ||||
else | else | ||||
eicr_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw); | eicr_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw); | ||||
if (eicr & eicr_mask) { | if (eicr & eicr_mask) { | ||||
IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask); | IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask); | ||||
if (atomic_cmpset_acq_int(&adapter->sfp_reinit, 0, 1)) | adapter->task_requests |= IXGBE_REQUEST_TASK_MOD; | ||||
GROUPTASK_ENQUEUE(&adapter->mod_task); | |||||
} | } | ||||
if ((hw->mac.type == ixgbe_mac_82599EB) && | if ((hw->mac.type == ixgbe_mac_82599EB) && | ||||
(eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) { | (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) { | ||||
IXGBE_WRITE_REG(hw, IXGBE_EICR, | IXGBE_WRITE_REG(hw, IXGBE_EICR, | ||||
IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); | IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); | ||||
if (atomic_cmpset_acq_int(&adapter->sfp_reinit, 0, 1)) | adapter->task_requests |= IXGBE_REQUEST_TASK_MSF; | ||||
GROUPTASK_ENQUEUE(&adapter->msf_task); | |||||
} | } | ||||
} | } | ||||
/* Check for fan failure */ | /* Check for fan failure */ | ||||
if (adapter->feat_en & IXGBE_FEATURE_FAN_FAIL) { | if (adapter->feat_en & IXGBE_FEATURE_FAN_FAIL) { | ||||
ixgbe_check_fan_failure(adapter, eicr, TRUE); | ixgbe_check_fan_failure(adapter, eicr, TRUE); | ||||
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); | IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); | ||||
} | } | ||||
/* External PHY interrupt */ | /* External PHY interrupt */ | ||||
if ((hw->phy.type == ixgbe_phy_x550em_ext_t) && | if ((hw->phy.type == ixgbe_phy_x550em_ext_t) && | ||||
(eicr & IXGBE_EICR_GPI_SDP0_X540)) { | (eicr & IXGBE_EICR_GPI_SDP0_X540)) { | ||||
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0_X540); | IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0_X540); | ||||
GROUPTASK_ENQUEUE(&adapter->phy_task); | adapter->task_requests |= IXGBE_REQUEST_TASK_PHY; | ||||
} | } | ||||
/* Re-enable other interrupts */ | return (adapter->task_requests != 0) ? FILTER_SCHEDULE_THREAD : FILTER_HANDLED; | ||||
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER); | |||||
return (FILTER_HANDLED); | |||||
} /* ixgbe_msix_link */ | } /* ixgbe_msix_link */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_sysctl_interrupt_rate_handler | * ixgbe_sysctl_interrupt_rate_handler | ||||
************************************************************************/ | ************************************************************************/ | ||||
static int | static int | ||||
ixgbe_sysctl_interrupt_rate_handler(SYSCTL_HANDLER_ARGS) | ixgbe_sysctl_interrupt_rate_handler(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | ixgbe_if_detach(if_ctx_t ctx) | ||||
INIT_DEBUGOUT("ixgbe_detach: begin"); | INIT_DEBUGOUT("ixgbe_detach: begin"); | ||||
if (ixgbe_pci_iov_detach(dev) != 0) { | if (ixgbe_pci_iov_detach(dev) != 0) { | ||||
device_printf(dev, "SR-IOV in use; detach first.\n"); | device_printf(dev, "SR-IOV in use; detach first.\n"); | ||||
return (EBUSY); | return (EBUSY); | ||||
} | } | ||||
iflib_config_gtask_deinit(&adapter->mod_task); | |||||
iflib_config_gtask_deinit(&adapter->msf_task); | |||||
iflib_config_gtask_deinit(&adapter->phy_task); | |||||
if (adapter->feat_cap & IXGBE_FEATURE_SRIOV) | |||||
iflib_config_gtask_deinit(&adapter->mbx_task); | |||||
ixgbe_setup_low_power_mode(ctx); | ixgbe_setup_low_power_mode(ctx); | ||||
/* let hardware know driver is unloading */ | /* let hardware know driver is unloading */ | ||||
ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT); | ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT); | ||||
ctrl_ext &= ~IXGBE_CTRL_EXT_DRV_LOAD; | ctrl_ext &= ~IXGBE_CTRL_EXT_DRV_LOAD; | ||||
IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT, ctrl_ext); | IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT, ctrl_ext); | ||||
ixgbe_free_pci_resources(ctx); | ixgbe_free_pci_resources(ctx); | ||||
▲ Show 20 Lines • Show All 242 Lines • ▼ Show 20 Lines | ixgbe_if_init(if_ctx_t ctx) | ||||
if (adapter->max_frame_size <= MCLBYTES) | if (adapter->max_frame_size <= MCLBYTES) | ||||
adapter->rx_mbuf_sz = MCLBYTES; | adapter->rx_mbuf_sz = MCLBYTES; | ||||
else | else | ||||
adapter->rx_mbuf_sz = MJUMPAGESIZE; | adapter->rx_mbuf_sz = MJUMPAGESIZE; | ||||
/* Configure RX settings */ | /* Configure RX settings */ | ||||
ixgbe_initialize_receive_units(ctx); | ixgbe_initialize_receive_units(ctx); | ||||
/* | |||||
* Initialize variable holding task enqueue requests | |||||
* from MSI-X interrupts | |||||
*/ | |||||
adapter->task_requests = 0; | |||||
/* Enable SDP & MSI-X interrupts based on adapter */ | /* Enable SDP & MSI-X interrupts based on adapter */ | ||||
ixgbe_config_gpie(adapter); | ixgbe_config_gpie(adapter); | ||||
/* Set MTU size */ | /* Set MTU size */ | ||||
if (ifp->if_mtu > ETHERMTU) { | if (ifp->if_mtu > ETHERMTU) { | ||||
/* aka IXGBE_MAXFRS on 82599 and newer */ | /* aka IXGBE_MAXFRS on 82599 and newer */ | ||||
mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); | mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); | ||||
mhadd &= ~IXGBE_MHADD_MFS_MASK; | mhadd &= ~IXGBE_MHADD_MFS_MASK; | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | ixgbe_if_init(if_ctx_t ctx) | ||||
/* Set moderation on the Link interrupt */ | /* Set moderation on the Link interrupt */ | ||||
IXGBE_WRITE_REG(hw, IXGBE_EITR(adapter->vector), IXGBE_LINK_ITR); | IXGBE_WRITE_REG(hw, IXGBE_EITR(adapter->vector), IXGBE_LINK_ITR); | ||||
/* Enable power to the phy. */ | /* Enable power to the phy. */ | ||||
ixgbe_set_phy_power(hw, TRUE); | ixgbe_set_phy_power(hw, TRUE); | ||||
/* Config/Enable Link */ | /* Config/Enable Link */ | ||||
ixgbe_config_link(adapter); | ixgbe_config_link(ctx); | ||||
/* Hardware Packet Buffer & Flow Control setup */ | /* Hardware Packet Buffer & Flow Control setup */ | ||||
ixgbe_config_delay_values(adapter); | ixgbe_config_delay_values(adapter); | ||||
/* Initialize the FC settings */ | /* Initialize the FC settings */ | ||||
ixgbe_start_hw(hw); | ixgbe_start_hw(hw); | ||||
/* Set up VLAN support and filter */ | /* Set up VLAN support and filter */ | ||||
▲ Show 20 Lines • Show All 346 Lines • ▼ Show 20 Lines | |||||
ixgbe_handle_mod(void *context) | ixgbe_handle_mod(void *context) | ||||
{ | { | ||||
if_ctx_t ctx = context; | if_ctx_t ctx = context; | ||||
struct adapter *adapter = iflib_get_softc(ctx); | struct adapter *adapter = iflib_get_softc(ctx); | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &adapter->hw; | ||||
device_t dev = iflib_get_dev(ctx); | device_t dev = iflib_get_dev(ctx); | ||||
u32 err, cage_full = 0; | u32 err, cage_full = 0; | ||||
adapter->sfp_reinit = 1; | |||||
if (adapter->hw.need_crosstalk_fix) { | if (adapter->hw.need_crosstalk_fix) { | ||||
switch (hw->mac.type) { | switch (hw->mac.type) { | ||||
case ixgbe_mac_82599EB: | case ixgbe_mac_82599EB: | ||||
cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) & | cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) & | ||||
IXGBE_ESDP_SDP2; | IXGBE_ESDP_SDP2; | ||||
break; | break; | ||||
case ixgbe_mac_X550EM_x: | case ixgbe_mac_X550EM_x: | ||||
case ixgbe_mac_X550EM_a: | case ixgbe_mac_X550EM_a: | ||||
Show All 20 Lines | ixgbe_handle_mod(void *context) | ||||
else | else | ||||
err = hw->mac.ops.setup_sfp(hw); | err = hw->mac.ops.setup_sfp(hw); | ||||
if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { | if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { | ||||
device_printf(dev, | device_printf(dev, | ||||
"Setup failure - unsupported SFP+ module type.\n"); | "Setup failure - unsupported SFP+ module type.\n"); | ||||
goto handle_mod_out; | goto handle_mod_out; | ||||
} | } | ||||
GROUPTASK_ENQUEUE(&adapter->msf_task); | adapter->task_requests |= IXGBE_REQUEST_TASK_MSF; | ||||
return; | return; | ||||
handle_mod_out: | handle_mod_out: | ||||
adapter->sfp_reinit = 0; | adapter->task_requests &= ~(IXGBE_REQUEST_TASK_MSF); | ||||
} /* ixgbe_handle_mod */ | } /* ixgbe_handle_mod */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_handle_msf - Tasklet for MSF (multispeed fiber) interrupts | * ixgbe_handle_msf - Tasklet for MSF (multispeed fiber) interrupts | ||||
************************************************************************/ | ************************************************************************/ | ||||
static void | static void | ||||
ixgbe_handle_msf(void *context) | ixgbe_handle_msf(void *context) | ||||
{ | { | ||||
if_ctx_t ctx = context; | if_ctx_t ctx = context; | ||||
struct adapter *adapter = iflib_get_softc(ctx); | struct adapter *adapter = iflib_get_softc(ctx); | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &adapter->hw; | ||||
u32 autoneg; | u32 autoneg; | ||||
bool negotiate; | bool negotiate; | ||||
if (adapter->sfp_reinit != 1) | |||||
return; | |||||
/* get_supported_phy_layer will call hw->phy.ops.identify_sfp() */ | /* get_supported_phy_layer will call hw->phy.ops.identify_sfp() */ | ||||
adapter->phy_layer = ixgbe_get_supported_physical_layer(hw); | adapter->phy_layer = ixgbe_get_supported_physical_layer(hw); | ||||
autoneg = hw->phy.autoneg_advertised; | autoneg = hw->phy.autoneg_advertised; | ||||
if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) | if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) | ||||
hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiate); | hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiate); | ||||
if (hw->mac.ops.setup_link) | if (hw->mac.ops.setup_link) | ||||
hw->mac.ops.setup_link(hw, autoneg, TRUE); | hw->mac.ops.setup_link(hw, autoneg, TRUE); | ||||
/* Adjust media types shown in ifconfig */ | /* Adjust media types shown in ifconfig */ | ||||
ifmedia_removeall(adapter->media); | ifmedia_removeall(adapter->media); | ||||
ixgbe_add_media_types(adapter->ctx); | ixgbe_add_media_types(adapter->ctx); | ||||
ifmedia_set(adapter->media, IFM_ETHER | IFM_AUTO); | ifmedia_set(adapter->media, IFM_ETHER | IFM_AUTO); | ||||
adapter->sfp_reinit = 0; | |||||
} /* ixgbe_handle_msf */ | } /* ixgbe_handle_msf */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_handle_phy - Tasklet for external PHY interrupts | * ixgbe_handle_phy - Tasklet for external PHY interrupts | ||||
************************************************************************/ | ************************************************************************/ | ||||
static void | static void | ||||
ixgbe_handle_phy(void *context) | ixgbe_handle_phy(void *context) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | if (adapter->link_active == TRUE) { | ||||
device_printf(dev, "Link is Down\n"); | device_printf(dev, "Link is Down\n"); | ||||
iflib_link_state_change(ctx, LINK_STATE_DOWN, 0); | iflib_link_state_change(ctx, LINK_STATE_DOWN, 0); | ||||
adapter->link_active = FALSE; | adapter->link_active = FALSE; | ||||
if (adapter->feat_en & IXGBE_FEATURE_SRIOV) | if (adapter->feat_en & IXGBE_FEATURE_SRIOV) | ||||
ixgbe_ping_all_vfs(adapter); | ixgbe_ping_all_vfs(adapter); | ||||
} | } | ||||
} | } | ||||
ixgbe_update_stats_counters(adapter); | /* Handle task requests from msix_link() */ | ||||
if (adapter->task_requests & IXGBE_REQUEST_TASK_MOD) | |||||
ixgbe_handle_mod(ctx); | |||||
if (adapter->task_requests & IXGBE_REQUEST_TASK_MSF) | |||||
ixgbe_handle_msf(ctx); | |||||
if (adapter->task_requests & IXGBE_REQUEST_TASK_MBX) | |||||
ixgbe_handle_mbx(ctx); | |||||
if (adapter->task_requests & IXGBE_REQUEST_TASK_FDIR) | |||||
ixgbe_reinit_fdir(ctx); | |||||
if (adapter->task_requests & IXGBE_REQUEST_TASK_PHY) | |||||
ixgbe_handle_phy(ctx); | |||||
adapter->task_requests = 0; | |||||
/* Re-enable link interrupts */ | ixgbe_update_stats_counters(adapter); | ||||
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, IXGBE_EIMS_LSC); | |||||
} /* ixgbe_if_update_admin_status */ | } /* ixgbe_if_update_admin_status */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_config_dmac - Configure DMA Coalescing | * ixgbe_config_dmac - Configure DMA Coalescing | ||||
************************************************************************/ | ************************************************************************/ | ||||
static void | static void | ||||
ixgbe_config_dmac(struct adapter *adapter) | ixgbe_config_dmac(struct adapter *adapter) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 119 Lines • ▼ Show 20 Lines | if (adapter->hw.mac.type == ixgbe_mac_82598EB) { | ||||
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), ~0); | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), ~0); | ||||
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0); | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0); | ||||
} | } | ||||
IXGBE_WRITE_FLUSH(&adapter->hw); | IXGBE_WRITE_FLUSH(&adapter->hw); | ||||
} /* ixgbe_if_disable_intr */ | } /* ixgbe_if_disable_intr */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_link_intr_enable | |||||
************************************************************************/ | |||||
static void | |||||
ixgbe_link_intr_enable(if_ctx_t ctx) | |||||
{ | |||||
struct ixgbe_hw *hw = &((struct adapter *)iflib_get_softc(ctx))->hw; | |||||
/* Re-enable other interrupts */ | |||||
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER | IXGBE_EIMS_LSC); | |||||
} /* ixgbe_link_intr_enable */ | |||||
/************************************************************************ | |||||
* ixgbe_if_rx_queue_intr_enable | * ixgbe_if_rx_queue_intr_enable | ||||
************************************************************************/ | ************************************************************************/ | ||||
static int | static int | ||||
ixgbe_if_rx_queue_intr_enable(if_ctx_t ctx, uint16_t rxqid) | ixgbe_if_rx_queue_intr_enable(if_ctx_t ctx, uint16_t rxqid) | ||||
{ | { | ||||
struct adapter *adapter = iflib_get_softc(ctx); | struct adapter *adapter = iflib_get_softc(ctx); | ||||
struct ix_rx_queue *que = &adapter->rx_queues[rxqid]; | struct ix_rx_queue *que = &adapter->rx_queues[rxqid]; | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | if (ixgbe_is_sfp(hw)) { | ||||
/* Pluggable optics-related interrupt */ | /* Pluggable optics-related interrupt */ | ||||
if (hw->mac.type >= ixgbe_mac_X540) | if (hw->mac.type >= ixgbe_mac_X540) | ||||
eicr_mask = IXGBE_EICR_GPI_SDP0_X540; | eicr_mask = IXGBE_EICR_GPI_SDP0_X540; | ||||
else | else | ||||
eicr_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw); | eicr_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw); | ||||
if (eicr & eicr_mask) { | if (eicr & eicr_mask) { | ||||
IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask); | IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask); | ||||
GROUPTASK_ENQUEUE(&adapter->mod_task); | adapter->task_requests |= IXGBE_REQUEST_TASK_MOD; | ||||
} | } | ||||
if ((hw->mac.type == ixgbe_mac_82599EB) && | if ((hw->mac.type == ixgbe_mac_82599EB) && | ||||
(eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) { | (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) { | ||||
IXGBE_WRITE_REG(hw, IXGBE_EICR, | IXGBE_WRITE_REG(hw, IXGBE_EICR, | ||||
IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); | IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); | ||||
if (atomic_cmpset_acq_int(&adapter->sfp_reinit, 0, 1)) | adapter->task_requests |= IXGBE_REQUEST_TASK_MSF; | ||||
GROUPTASK_ENQUEUE(&adapter->msf_task); | |||||
} | } | ||||
} | } | ||||
/* External PHY interrupt */ | /* External PHY interrupt */ | ||||
if ((hw->phy.type == ixgbe_phy_x550em_ext_t) && | if ((hw->phy.type == ixgbe_phy_x550em_ext_t) && | ||||
(eicr & IXGBE_EICR_GPI_SDP0_X540)) | (eicr & IXGBE_EICR_GPI_SDP0_X540)) | ||||
GROUPTASK_ENQUEUE(&adapter->phy_task); | adapter->task_requests |= IXGBE_REQUEST_TASK_PHY; | ||||
return (FILTER_SCHEDULE_THREAD); | return (FILTER_SCHEDULE_THREAD); | ||||
} /* ixgbe_intr */ | } /* ixgbe_intr */ | ||||
/************************************************************************ | /************************************************************************ | ||||
* ixgbe_free_pci_resources | * ixgbe_free_pci_resources | ||||
************************************************************************/ | ************************************************************************/ | ||||
static void | static void | ||||
▲ Show 20 Lines • Show All 746 Lines • Show Last 20 Lines |