aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ice/if_ice_iflib.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ice/if_ice_iflib.c')
-rw-r--r--sys/dev/ice/if_ice_iflib.c130
1 files changed, 105 insertions, 25 deletions
diff --git a/sys/dev/ice/if_ice_iflib.c b/sys/dev/ice/if_ice_iflib.c
index 8d03bdfd23fb..e43c05081098 100644
--- a/sys/dev/ice/if_ice_iflib.c
+++ b/sys/dev/ice/if_ice_iflib.c
@@ -83,7 +83,7 @@ static int ice_if_priv_ioctl(if_ctx_t ctx, u_long command, caddr_t data);
static int ice_if_i2c_req(if_ctx_t ctx, struct ifi2creq *req);
static int ice_if_suspend(if_ctx_t ctx);
static int ice_if_resume(if_ctx_t ctx);
-static bool ice_if_needs_restart(if_ctx_t, enum iflib_restart_event);
+static bool ice_if_needs_restart(if_ctx_t ctx, enum iflib_restart_event event);
static int ice_msix_que(void *arg);
static int ice_msix_admin(void *arg);
@@ -110,6 +110,7 @@ static int ice_allocate_msix(struct ice_softc *sc);
static void ice_admin_timer(void *arg);
static void ice_transition_recovery_mode(struct ice_softc *sc);
static void ice_transition_safe_mode(struct ice_softc *sc);
+static void ice_set_default_promisc_mask(ice_bitmap_t *promisc_mask);
/*
* Device Interface Declaration
@@ -342,6 +343,7 @@ ice_setup_scctx(struct ice_softc *sc)
{
if_softc_ctx_t scctx = sc->scctx;
struct ice_hw *hw = &sc->hw;
+ device_t dev = sc->dev;
bool safe_mode, recovery_mode;
safe_mode = ice_is_bit_set(sc->feat_en, ICE_FEATURE_SAFE_MODE);
@@ -393,7 +395,7 @@ ice_setup_scctx(struct ice_softc *sc)
scctx->isc_tx_tso_size_max = ICE_TSO_SIZE;
scctx->isc_tx_tso_segsize_max = ICE_MAX_DMA_SEG_SIZE;
- scctx->isc_msix_bar = PCIR_BAR(ICE_MSIX_BAR);
+ scctx->isc_msix_bar = pci_msix_table_bar(dev);
scctx->isc_rss_table_size = hw->func_caps.common_cap.rss_table_size;
/*
@@ -512,6 +514,9 @@ reinit_hw:
ice_init_device_features(sc);
+ /* Keep flag set by default */
+ ice_set_state(&sc->state, ICE_STATE_LINK_ACTIVE_ON_DOWN);
+
/* Notify firmware of the device driver version */
err = ice_send_version(sc);
if (err)
@@ -695,7 +700,8 @@ ice_update_link_status(struct ice_softc *sc, bool update_media)
if (sc->link_up) { /* link is up */
uint64_t baudrate = ice_aq_speed_to_rate(sc->hw.port_info);
- ice_set_default_local_lldp_mib(sc);
+ if (!(hw->port_info->phy.link_info_old.link_info & ICE_AQ_LINK_UP))
+ ice_set_default_local_lldp_mib(sc);
iflib_link_state_change(sc->ctx, LINK_STATE_UP, baudrate);
ice_rdma_link_change(sc, LINK_STATE_UP, baudrate);
@@ -709,7 +715,7 @@ ice_update_link_status(struct ice_softc *sc, bool update_media)
}
/* Update the supported media types */
- if (update_media) {
+ if (update_media && !ice_test_state(&sc->state, ICE_STATE_PREPARED_FOR_RESET)) {
status = ice_add_media_types(sc, sc->media);
if (status)
device_printf(sc->dev, "Error adding device media types: %s aq_err %s\n",
@@ -731,6 +737,7 @@ ice_if_attach_post(if_ctx_t ctx)
{
struct ice_softc *sc = (struct ice_softc *)iflib_get_softc(ctx);
if_t ifp = iflib_get_ifp(ctx);
+ enum ice_status status;
int err;
ASSERT_CTX_LOCKED(sc);
@@ -793,6 +800,15 @@ ice_if_attach_post(if_ctx_t ctx)
ice_cfg_pba_num(sc);
+ /* Set a default value for PFC mode on attach since the FW state is unknown
+ * before sysctl tunables are executed and it can't be queried. This fixes an
+ * issue when loading the driver with the FW LLDP agent enabled but the FW
+ * was previously in DSCP PFC mode.
+ */
+ status = ice_aq_set_pfc_mode(&sc->hw, ICE_AQC_PFC_VLAN_BASED_PFC, NULL);
+ if (status != ICE_SUCCESS)
+ device_printf(sc->dev, "Setting pfc mode failed, status %s\n", ice_status_str(status));
+
ice_add_device_sysctls(sc);
/* Get DCBX/LLDP state and start DCBX agent */
@@ -817,6 +833,10 @@ ice_if_attach_post(if_ctx_t ctx)
callout_reset(&sc->admin_timer, hz/2, ice_admin_timer, sc);
mtx_unlock(&sc->admin_mtx);
+ if (ice_test_state(&sc->state, ICE_STATE_LINK_ACTIVE_ON_DOWN) &&
+ !ice_test_state(&sc->state, ICE_STATE_NO_MEDIA))
+ ice_set_state(&sc->state, ICE_STATE_FIRST_INIT_LINK);
+
ice_clear_state(&sc->state, ICE_STATE_ATTACHING);
return 0;
@@ -895,6 +915,7 @@ ice_if_detach(if_ctx_t ctx)
{
struct ice_softc *sc = (struct ice_softc *)iflib_get_softc(ctx);
struct ice_vsi *vsi = &sc->pf_vsi;
+ enum ice_status status;
int i;
ASSERT_CTX_LOCKED(sc);
@@ -953,6 +974,14 @@ ice_if_detach(if_ctx_t ctx)
if (!ice_test_state(&sc->state, ICE_STATE_RECOVERY_MODE))
ice_deinit_hw(&sc->hw);
+ IFLIB_CTX_UNLOCK(sc);
+ status = ice_reset(&sc->hw, ICE_RESET_PFR);
+ IFLIB_CTX_LOCK(sc);
+ if (status) {
+ device_printf(sc->dev, "device PF reset failed, err %s\n",
+ ice_status_str(status));
+ }
+
ice_free_pci_mapping(sc);
return 0;
@@ -1733,6 +1762,25 @@ ice_if_tx_queue_intr_enable(if_ctx_t ctx, uint16_t txqid)
}
/**
+ * ice_set_default_promisc_mask - Set default config for promisc settings
+ * @promisc_mask: bitmask to setup
+ *
+ * The ice_(set|clear)_vsi_promisc() function expects a mask of promiscuous
+ * modes to operate on. The mask used in here is the default one for the
+ * driver, where promiscuous is enabled/disabled for all types of
+ * non-VLAN-tagged/VLAN 0 traffic.
+ */
+static void
+ice_set_default_promisc_mask(ice_bitmap_t *promisc_mask)
+{
+ ice_zero_bitmap(promisc_mask, ICE_PROMISC_MAX);
+ ice_set_bit(ICE_PROMISC_UCAST_TX, promisc_mask);
+ ice_set_bit(ICE_PROMISC_UCAST_RX, promisc_mask);
+ ice_set_bit(ICE_PROMISC_MCAST_TX, promisc_mask);
+ ice_set_bit(ICE_PROMISC_MCAST_RX, promisc_mask);
+}
+
+/**
* ice_if_promisc_set - Set device promiscuous mode
* @ctx: iflib context structure
* @flags: promiscuous flags to configure
@@ -1750,17 +1798,20 @@ ice_if_promisc_set(if_ctx_t ctx, int flags)
enum ice_status status;
bool promisc_enable = flags & IFF_PROMISC;
bool multi_enable = flags & IFF_ALLMULTI;
+ ice_declare_bitmap(promisc_mask, ICE_PROMISC_MAX);
/* Do not support configuration when in recovery mode */
if (ice_test_state(&sc->state, ICE_STATE_RECOVERY_MODE))
return (ENOSYS);
+
+ ice_set_default_promisc_mask(promisc_mask);
if (multi_enable)
return (EOPNOTSUPP);
if (promisc_enable) {
status = ice_set_vsi_promisc(hw, sc->pf_vsi.idx,
- ICE_VSI_PROMISC_MASK, 0);
+ promisc_mask, 0);
if (status && status != ICE_ERR_ALREADY_EXISTS) {
device_printf(dev,
"Failed to enable promiscuous mode for PF VSI, err %s aq_err %s\n",
@@ -1770,7 +1821,7 @@ ice_if_promisc_set(if_ctx_t ctx, int flags)
}
} else {
status = ice_clear_vsi_promisc(hw, sc->pf_vsi.idx,
- ICE_VSI_PROMISC_MASK, 0);
+ promisc_mask, 0);
if (status) {
device_printf(dev,
"Failed to disable promiscuous mode for PF VSI, err %s aq_err %s\n",
@@ -1983,6 +2034,11 @@ ice_if_init(if_ctx_t ctx)
/* Configure promiscuous mode */
ice_if_promisc_set(ctx, if_getflags(sc->ifp));
+ if (!ice_testandclear_state(&sc->state, ICE_STATE_FIRST_INIT_LINK))
+ if (!sc->link_up && ((if_getflags(sc->ifp) & IFF_UP) ||
+ ice_test_state(&sc->state, ICE_STATE_LINK_ACTIVE_ON_DOWN)))
+ ice_set_link(sc, true);
+
ice_rdma_pf_init(sc);
ice_set_state(&sc->state, ICE_STATE_DRIVER_INITIALIZED);
@@ -2020,14 +2076,18 @@ ice_poll_for_media_avail(struct ice_softc *sc)
enum ice_status status;
/* Re-enable link and re-apply user link settings */
- ice_apply_saved_phy_cfg(sc, ICE_APPLY_LS_FEC_FC);
-
- /* Update the OS about changes in media capability */
- status = ice_add_media_types(sc, sc->media);
- if (status)
- device_printf(sc->dev, "Error adding device media types: %s aq_err %s\n",
- ice_status_str(status),
- ice_aq_str(hw->adminq.sq_last_status));
+ if (ice_test_state(&sc->state, ICE_STATE_LINK_ACTIVE_ON_DOWN) ||
+ (if_getflags(sc->ifp) & IFF_UP)) {
+ ice_apply_saved_phy_cfg(sc, ICE_APPLY_LS_FEC_FC);
+
+ /* Update the OS about changes in media capability */
+ status = ice_add_media_types(sc, sc->media);
+ if (status)
+ device_printf(sc->dev,
+ "Error adding device media types: %s aq_err %s\n",
+ ice_status_str(status),
+ ice_aq_str(hw->adminq.sq_last_status));
+ }
ice_clear_state(&sc->state, ICE_STATE_NO_MEDIA);
}
@@ -2311,7 +2371,7 @@ ice_prepare_for_reset(struct ice_softc *sc)
ice_clear_hw_tbls(hw);
if (hw->port_info)
- ice_sched_clear_port(hw->port_info);
+ ice_sched_cleanup_all(hw);
ice_shutdown_all_ctrlq(hw, false);
}
@@ -2554,6 +2614,9 @@ ice_rebuild(struct ice_softc *sc)
goto err_deinit_pf_vsi;
}
+ if (hw->port_info->qos_cfg.is_sw_lldp)
+ ice_add_rx_lldp_filter(sc);
+
/* Refresh link status */
ice_clear_state(&sc->state, ICE_STATE_LINK_STATUS_REPORTED);
sc->hw.port_info->phy.get_link_info = true;
@@ -2578,8 +2641,13 @@ ice_rebuild(struct ice_softc *sc)
* because the state of IFC_DO_RESET is cached within task_fn_admin in
* the iflib core, we also want re-run the admin task so that iflib
* resets immediately instead of waiting for the next interrupt.
+ * If LLDP is enabled we need to reconfig DCB to properly reinit all TC
+ * queues, not only 0. It contains ice_request_stack_reinit as well.
*/
- ice_request_stack_reinit(sc);
+ if (hw->port_info->qos_cfg.is_sw_lldp)
+ ice_request_stack_reinit(sc);
+ else
+ ice_do_dcb_reconfig(sc, false);
return;
@@ -2706,6 +2774,8 @@ ice_handle_pf_reset_request(struct ice_softc *sc)
static void
ice_init_device_features(struct ice_softc *sc)
{
+ struct ice_hw *hw = &sc->hw;
+
/* Set capabilities that all devices support */
ice_set_bit(ICE_FEATURE_SRIOV, sc->feat_cap);
ice_set_bit(ICE_FEATURE_RSS, sc->feat_cap);
@@ -2720,22 +2790,22 @@ ice_init_device_features(struct ice_softc *sc)
ice_set_bit(ICE_FEATURE_TX_BALANCE, sc->feat_cap);
/* Disable features due to hardware limitations... */
- if (!sc->hw.func_caps.common_cap.rss_table_size)
+ if (!hw->func_caps.common_cap.rss_table_size)
ice_clear_bit(ICE_FEATURE_RSS, sc->feat_cap);
- if (!sc->hw.func_caps.common_cap.iwarp || !ice_enable_irdma)
+ if (!hw->func_caps.common_cap.iwarp || !ice_enable_irdma)
ice_clear_bit(ICE_FEATURE_RDMA, sc->feat_cap);
- if (!sc->hw.func_caps.common_cap.dcb)
+ if (!hw->func_caps.common_cap.dcb)
ice_clear_bit(ICE_FEATURE_DCB, sc->feat_cap);
/* Disable features due to firmware limitations... */
- if (!ice_is_fw_health_report_supported(&sc->hw))
+ if (!ice_is_fw_health_report_supported(hw))
ice_clear_bit(ICE_FEATURE_HEALTH_STATUS, sc->feat_cap);
- if (!ice_fwlog_supported(&sc->hw))
+ if (!ice_fwlog_supported(hw))
ice_clear_bit(ICE_FEATURE_FW_LOGGING, sc->feat_cap);
- if (sc->hw.fwlog_cfg.options & ICE_FWLOG_OPTION_IS_REGISTERED) {
+ if (hw->fwlog_cfg.options & ICE_FWLOG_OPTION_IS_REGISTERED) {
if (ice_is_bit_set(sc->feat_cap, ICE_FEATURE_FW_LOGGING))
ice_set_bit(ICE_FEATURE_FW_LOGGING, sc->feat_en);
else
- ice_fwlog_unregister(&sc->hw);
+ ice_fwlog_unregister(hw);
}
/* Disable capabilities not supported by the OS */
@@ -2748,6 +2818,11 @@ ice_init_device_features(struct ice_softc *sc)
/* Disable features based on sysctl settings */
if (!ice_tx_balance_en)
ice_clear_bit(ICE_FEATURE_TX_BALANCE, sc->feat_cap);
+
+ if (hw->dev_caps.supported_sensors & ICE_SENSOR_SUPPORT_E810_INT_TEMP) {
+ ice_set_bit(ICE_FEATURE_TEMP_SENSOR, sc->feat_cap);
+ ice_set_bit(ICE_FEATURE_TEMP_SENSOR, sc->feat_en);
+ }
}
/**
@@ -2898,6 +2973,10 @@ ice_if_stop(if_ctx_t ctx)
/* Disable the Tx and Rx queues */
ice_vsi_disable_tx(&sc->pf_vsi);
ice_control_all_rx_queues(&sc->pf_vsi, false);
+
+ if (!ice_test_state(&sc->state, ICE_STATE_LINK_ACTIVE_ON_DOWN) &&
+ !(if_getflags(sc->ifp) & IFF_UP) && sc->link_up)
+ ice_set_link(sc, false);
}
/**
@@ -3078,8 +3157,9 @@ ice_if_resume(if_ctx_t ctx)
return (0);
}
-/* ice_if_needs_restart - Tell iflib when the driver needs to be reinitialized
- * @ctx: iflib context
+/**
+ * ice_if_needs_restart - Tell iflib when the driver needs to be reinitialized
+ * @ctx: iflib context pointer
* @event: event code to check
*
* Defaults to returning false for unknown events.