Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107148861
D28028.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D28028.diff
View Options
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
@@ -770,6 +770,12 @@
ixl_update_stats_counters(pf);
ixl_add_hw_stats(pf);
+ /*
+ * Driver may have been reloaded. Ensure that the link state
+ * is consistent with current settings.
+ */
+ ixl_set_link(pf, (pf->state & IXL_PF_STATE_LINK_ACTIVE_ON_DOWN) != 0);
+
hw->phy.get_link_info = true;
i40e_get_link_status(hw, &pf->link_up);
ixl_update_link_status(pf);
@@ -961,6 +967,8 @@
return;
}
+ ixl_set_link(pf, true);
+
/* Reconfigure multicast filters in HW */
ixl_if_multi_set(ctx);
@@ -1003,6 +1011,7 @@
ixl_if_stop(if_ctx_t ctx)
{
struct ixl_pf *pf = iflib_get_softc(ctx);
+ struct ifnet *ifp = iflib_get_ifp(ctx);
struct ixl_vsi *vsi = &pf->vsi;
INIT_DEBUGOUT("ixl_if_stop: begin\n");
@@ -1019,6 +1028,15 @@
ixl_disable_rings_intr(vsi);
ixl_disable_rings(pf, vsi, &pf->qtag);
+
+ /*
+ * Don't set link state if only reconfiguring
+ * e.g. on MTU change.
+ */
+ if ((if_getflags(ifp) & IFF_UP) == 0 &&
+ (atomic_load_acq_32(&pf->state) &
+ IXL_PF_STATE_LINK_ACTIVE_ON_DOWN) == 0)
+ ixl_set_link(pf, false);
}
static int
diff --git a/sys/dev/ixl/ixl_pf.h b/sys/dev/ixl/ixl_pf.h
--- a/sys/dev/ixl/ixl_pf.h
+++ b/sys/dev/ixl/ixl_pf.h
@@ -88,6 +88,7 @@
IXL_PF_STATE_EMP_RESET_REQ = (1 << 8),
IXL_PF_STATE_FW_LLDP_DISABLED = (1 << 9),
IXL_PF_STATE_EEE_ENABLED = (1 << 10),
+ IXL_PF_STATE_LINK_ACTIVE_ON_DOWN = (1 << 11),
};
#define IXL_PF_IN_RECOVERY_MODE(pf) \
@@ -229,6 +230,11 @@
"\t0 - disable\n" \
"\t1 - enable\n"
+#define IXL_SYSCTL_HELP_SET_LINK_ACTIVE \
+"\nKeep link active after setting interface down:\n" \
+"\t0 - disable\n" \
+"\t1 - enable\n"
+
#define IXL_SYSCTL_HELP_READ_I2C \
"\nRead a byte from I2C bus\n" \
"Input: 32-bit value\n" \
@@ -351,6 +357,7 @@
void ixl_get_bus_info(struct ixl_pf *pf);
int ixl_aq_get_link_status(struct ixl_pf *,
struct i40e_aqc_get_link_status *);
+void ixl_set_link(struct ixl_pf *, bool);
int ixl_handle_nvmupd_cmd(struct ixl_pf *, struct ifdrv *);
int ixl_handle_i2c_eeprom_read_cmd(struct ixl_pf *, struct ifreq *ifr);
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
@@ -413,6 +413,8 @@
/* Print out message if an unqualified module is found */
if ((status->link_info & I40E_AQ_MEDIA_AVAILABLE) &&
(pf->advertised_speed) &&
+ (atomic_load_32(&pf->state) &
+ IXL_PF_STATE_LINK_ACTIVE_ON_DOWN) != 0 &&
(!(status->an_info & I40E_AQ_QUALIFIED_MODULE)) &&
(!(status->link_info & I40E_AQ_LINK_UP)))
device_printf(dev, "Link failed because "
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
@@ -62,6 +62,7 @@
static int ixl_sysctl_pf_rx_itr(SYSCTL_HANDLER_ARGS);
static int ixl_sysctl_eee_enable(SYSCTL_HANDLER_ARGS);
+static int ixl_sysctl_set_link_active(SYSCTL_HANDLER_ARGS);
/* Debug Sysctls */
static int ixl_sysctl_link_status(SYSCTL_HANDLER_ARGS);
@@ -385,6 +386,9 @@
break;
}
+ /* Keep link active by default */
+ atomic_set_32(&pf->state, IXL_PF_STATE_LINK_ACTIVE_ON_DOWN);
+
/* Print a subset of the capability information. */
device_printf(dev,
"PF-ID[%d]: VFs %d, MSI-X %d, VF MSI-X %d, QPs %d, %s\n",
@@ -2499,6 +2503,12 @@
CTLFLAG_RD | CTLFLAG_MPSAFE, &pf->stats.rx_lpi_count,
"RX LPI count");
+ SYSCTL_ADD_PROC(ctx, ctx_list, OID_AUTO,
+ "link_active_on_if_down",
+ CTLTYPE_INT | CTLFLAG_RWTUN,
+ pf, 0, ixl_sysctl_set_link_active, "I",
+ IXL_SYSCTL_HELP_SET_LINK_ACTIVE);
+
/* Add sysctls meant to print debug information, but don't list them
* in "sysctl -a" output. */
debug_node = SYSCTL_ADD_NODE(ctx, ctx_list,
@@ -2519,6 +2529,11 @@
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
pf, 0, ixl_sysctl_link_status, "A", IXL_SYSCTL_HELP_LINK_STATUS);
+ SYSCTL_ADD_PROC(ctx, debug_list,
+ OID_AUTO, "phy_abilities_init",
+ CTLTYPE_STRING | CTLFLAG_RD,
+ pf, 1, ixl_sysctl_phy_abilities, "A", "Initial PHY Abilities");
+
SYSCTL_ADD_PROC(ctx, debug_list,
OID_AUTO, "phy_abilities",
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
@@ -3107,6 +3122,95 @@
return (-1);
}
+void
+ixl_set_link(struct ixl_pf *pf, bool enable)
+{
+ struct i40e_hw *hw = &pf->hw;
+ device_t dev = pf->dev;
+ struct i40e_aq_get_phy_abilities_resp abilities;
+ struct i40e_aq_set_phy_config config;
+ enum i40e_status_code aq_error = 0;
+ u32 phy_type, phy_type_ext;
+
+ /* Get initial capability information */
+ aq_error = i40e_aq_get_phy_capabilities(hw,
+ FALSE, TRUE, &abilities, NULL);
+ if (aq_error) {
+ device_printf(dev,
+ "%s: Error getting phy capabilities %d,"
+ " aq error: %d\n", __func__, aq_error,
+ hw->aq.asq_last_status);
+ return;
+ }
+
+ phy_type = abilities.phy_type;
+ phy_type_ext = abilities.phy_type_ext;
+
+ /* Get current capability information */
+ aq_error = i40e_aq_get_phy_capabilities(hw,
+ FALSE, FALSE, &abilities, NULL);
+ if (aq_error) {
+ device_printf(dev,
+ "%s: Error getting phy capabilities %d,"
+ " aq error: %d\n", __func__, aq_error,
+ hw->aq.asq_last_status);
+ return;
+ }
+
+ /* Prepare new config */
+ memset(&config, 0, sizeof(config));
+ config.link_speed = abilities.link_speed;
+ config.abilities = abilities.abilities;
+ config.eee_capability = abilities.eee_capability;
+ config.eeer = abilities.eeer_val;
+ config.low_power_ctrl = abilities.d3_lpan;
+ config.fec_config = abilities.fec_cfg_curr_mod_ext_info
+ & I40E_AQ_PHY_FEC_CONFIG_MASK;
+ config.phy_type = 0;
+ config.phy_type_ext = 0;
+
+ 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);
+ if (aq_error) {
+ device_printf(dev,
+ "%s: Error setting new phy config %d,"
+ " aq error: %d\n", __func__, aq_error,
+ hw->aq.asq_last_status);
+ return;
+ }
+
+ aq_error = i40e_aq_set_link_restart_an(hw, enable, NULL);
+ if (aq_error) {
+ device_printf(dev,
+ "%s: Error set link config %d,"
+ " aq error: %d\n", __func__, aq_error,
+ hw->aq.asq_last_status);
+ return;
+ }
+}
+
static char *
ixl_phy_type_string(u32 bit_pos, bool ext)
{
@@ -3265,7 +3369,7 @@
}
status = i40e_aq_get_phy_capabilities(hw,
- FALSE, FALSE, &abilities, NULL);
+ FALSE, arg2 != 0, &abilities, NULL);
if (status) {
device_printf(dev,
"%s: i40e_aq_get_phy_capabilities() status %s, aq error %s\n",
@@ -4447,6 +4551,28 @@
return (0);
}
+static int
+ixl_sysctl_set_link_active(SYSCTL_HANDLER_ARGS)
+{
+ struct ixl_pf *pf = (struct ixl_pf *)arg1;
+ int error, state;
+
+ state = !!(atomic_load_acq_32(&pf->state) &
+ IXL_PF_STATE_LINK_ACTIVE_ON_DOWN);
+
+ error = sysctl_handle_int(oidp, &state, 0, req);
+ if ((error) || (req->newptr == NULL))
+ return (error);
+
+ if (state == 0)
+ atomic_clear_32(&pf->state, IXL_PF_STATE_LINK_ACTIVE_ON_DOWN);
+ else
+ atomic_set_32(&pf->state, IXL_PF_STATE_LINK_ACTIVE_ON_DOWN);
+
+ return (0);
+}
+
+
int
ixl_attach_get_link_status(struct ixl_pf *pf)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jan 11, 9:11 PM (20 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15757847
Default Alt Text
D28028.diff (7 KB)
Attached To
Mode
D28028: ixl(4): Add ability to control link state on ifconfig down
Attached
Detach File
Event Timeline
Log In to Comment