diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c --- a/sys/dev/ixl/if_ixl.c +++ b/sys/dev/ixl/if_ixl.c @@ -304,6 +304,10 @@ SYSCTL_INT(_hw_ixl, OID_AUTO, tx_itr, CTLFLAG_RDTUN, &ixl_tx_itr, 0, "TX Interrupt Rate"); +static int ixl_flow_control = -1; +SYSCTL_INT(_hw_ixl, OID_AUTO, flow_control, CTLFLAG_RDTUN, + &ixl_flow_control, 0, "Initial Flow Control setting"); + #ifdef IXL_IW int ixl_enable_iwarp = 0; TUNABLE_INT("hw.ixl.enable_iwarp", &ixl_enable_iwarp); @@ -1892,5 +1896,20 @@ pf->rx_itr = IXL_ITR_8K; } else pf->rx_itr = ixl_rx_itr; + + pf->fc = -1; + if (ixl_flow_control != -1) { + if (ixl_flow_control < 0 || ixl_flow_control > 3) { + device_printf(dev, + "Invalid flow_control value of %d set!\n", + ixl_flow_control); + device_printf(dev, + "flow_control must be between %d and %d, " + "inclusive\n", 0, 3); + device_printf(dev, + "Using default configuration instead\n"); + } else + pf->fc = ixl_flow_control; + } } diff --git a/sys/dev/ixl/ixl_pf_iflib.c b/sys/dev/ixl/ixl_pf_iflib.c --- a/sys/dev/ixl/ixl_pf_iflib.c +++ b/sys/dev/ixl/ixl_pf_iflib.c @@ -1094,7 +1094,7 @@ aq_error = i40e_set_fc(hw, &fc_aq_err, TRUE); if (aq_error) { device_printf(dev, - "%s: Error setting new fc mode %d; fc_err %#x\n", + "%s: Error setting Flow Control mode %d; fc_err %#x\n", __func__, aq_error, fc_aq_err); return (EIO); } diff --git a/sys/dev/ixl/ixl_pf_main.c b/sys/dev/ixl/ixl_pf_main.c --- a/sys/dev/ixl/ixl_pf_main.c +++ b/sys/dev/ixl/ixl_pf_main.c @@ -3169,27 +3169,28 @@ config.phy_type = 0; config.phy_type_ext = 0; + config.abilities &= ~(I40E_AQ_PHY_FLAG_PAUSE_TX | + I40E_AQ_PHY_FLAG_PAUSE_RX); + + switch (pf->fc) { + case I40E_FC_FULL: + config.abilities |= I40E_AQ_PHY_FLAG_PAUSE_TX | + I40E_AQ_PHY_FLAG_PAUSE_RX; + break; + case I40E_FC_RX_PAUSE: + config.abilities |= I40E_AQ_PHY_FLAG_PAUSE_RX; + break; + case I40E_FC_TX_PAUSE: + config.abilities |= I40E_AQ_PHY_FLAG_PAUSE_TX; + break; + default: + break; + } + if (enable) { config.phy_type = phy_type; config.phy_type_ext = phy_type_ext; - config.abilities &= ~(I40E_AQ_PHY_FLAG_PAUSE_TX | - I40E_AQ_PHY_FLAG_PAUSE_RX); - - switch (pf->fc) { - case I40E_FC_FULL: - config.abilities |= I40E_AQ_PHY_FLAG_PAUSE_TX | - I40E_AQ_PHY_FLAG_PAUSE_RX; - break; - case I40E_FC_RX_PAUSE: - config.abilities |= I40E_AQ_PHY_FLAG_PAUSE_RX; - break; - case I40E_FC_TX_PAUSE: - config.abilities |= I40E_AQ_PHY_FLAG_PAUSE_TX; - break; - default: - break; - } } aq_error = i40e_aq_set_phy_config(hw, &config, NULL); @@ -4594,6 +4595,11 @@ /* Determine link state */ hw->phy.get_link_info = TRUE; i40e_get_link_status(hw, &pf->link_up); + + /* Flow Control mode not set by user, read current FW settings */ + if (pf->fc == -1) + pf->fc = hw->fc.current_mode; + return (0); }