bool autoneg_wait_to_complete);
static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
+static bool ixgbe_mng_enabled(struct ixgbe_hw *hw)
+{
+ u32 fwsm, manc, factps;
+
+ fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM);
+ if ((fwsm & IXGBE_FWSM_MODE_MASK) != IXGBE_FWSM_FW_MODE_PT)
+ return false;
+
+ manc = IXGBE_READ_REG(hw, IXGBE_MANC);
+ if (!(manc & IXGBE_MANC_RCV_TCO_EN))
+ return false;
+
+ factps = IXGBE_READ_REG(hw, IXGBE_FACTPS);
+ if (factps & IXGBE_FACTPS_MNGCG)
+ return false;
+
+ return true;
+}
+
static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
{
struct ixgbe_mac_info *mac = &hw->mac;
- /* enable the laser control functions for SFP+ fiber */
- if (mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) {
+ /* enable the laser control functions for SFP+ fiber
+ * and MNG not enabled
+ */
+ if ((mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) &&
+ !hw->mng_fw_enabled) {
mac->ops.disable_tx_laser =
&ixgbe_disable_tx_laser_multispeed_fiber;
mac->ops.enable_tx_laser =
return status;
/* Flap the tx laser if it has not already been done */
- hw->mac.ops.flap_tx_laser(hw);
+ if (hw->mac.ops.flap_tx_laser)
+ hw->mac.ops.flap_tx_laser(hw);
/*
* Wait for the controller to acquire link. Per IEEE 802.3ap,
return status;
/* Flap the tx laser if it has not already been done */
- hw->mac.ops.flap_tx_laser(hw);
+ if (hw->mac.ops.flap_tx_laser)
+ hw->mac.ops.flap_tx_laser(hw);
/* Wait for the link partner to also set speed */
msleep(100);
ixgbe_link_speed link_speed;
s32 status;
u32 ctrl, i, autoc, autoc2;
+ u32 curr_lms;
bool link_up = false;
/* Call adapter stop to disable tx/rx and clear interrupts */
if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL)
hw->phy.ops.reset(hw);
+ /* remember AUTOC LMS from before we reset */
+ curr_lms = IXGBE_READ_REG(hw, IXGBE_AUTOC) & IXGBE_AUTOC_LMS_MASK;
+
mac_reset_top:
/*
* Issue global reset to the MAC. Needs to be SW reset if link is up.
hw->mac.orig_autoc2 = autoc2;
hw->mac.orig_link_settings_stored = true;
} else {
+
+ /* If MNG FW is running on a multi-speed device that
+ * doesn't autoneg with out driver support we need to
+ * leave LMS in the state it was before we MAC reset.
+ */
+ if (hw->phy.multispeed_fiber && hw->mng_fw_enabled)
+ hw->mac.orig_autoc =
+ (hw->mac.orig_autoc & ~IXGBE_AUTOC_LMS_MASK) |
+ curr_lms;
+
if (autoc != hw->mac.orig_autoc) {
/* Need SW/FW semaphore around AUTOC writes if LESM is
* on, likewise reset_pipeline requires us to hold
.release_swfw_sync = &ixgbe_release_swfw_sync,
.get_thermal_sensor_data = &ixgbe_get_thermal_sensor_data_generic,
.init_thermal_sensor_thresh = &ixgbe_init_thermal_sensor_thresh_generic,
-
+ .mng_fw_enabled = &ixgbe_mng_enabled,
};
static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
if (err)
goto err_sw_init;
+ /* Cache if MNG FW is up so we don't have to read the REG later */
+ if (hw->mac.ops.mng_fw_enabled)
+ hw->mng_fw_enabled = hw->mac.ops.mng_fw_enabled(hw);
+
/* Make it possible the adapter to be woken up via WOL */
switch (adapter->hw.mac.type) {
case ixgbe_mac_82599EB:
ixgbe_dbg_adapter_init(adapter);
#endif /* CONFIG_DEBUG_FS */
+ /* Need link setup for MNG FW, else wait for IXGBE_UP */
+ if (hw->mng_fw_enabled && hw->mac.ops.setup_link)
+ hw->mac.ops.setup_link(hw,
+ IXGBE_LINK_SPEED_10GB_FULL | IXGBE_LINK_SPEED_1GB_FULL,
+ true);
+
return 0;
err_register:
#define IXGBE_MDEF_EXT(_i) (0x05160 + ((_i) * 4)) /* 8 of these (0-7) */
#define IXGBE_LSWFW 0x15014
+/* Management Bit Fields and Masks */
+#define IXGBE_MANC_RCV_TCO_EN 0x00020000 /* Rcv TCO packet enable */
+
+/* Firmware Semaphore Register */
+#define IXGBE_FWSM_MODE_MASK 0xE
+#define IXGBE_FWSM_FW_MODE_PT 0x4
+
/* ARC Subsystem registers */
#define IXGBE_HICR 0x15F00
#define IXGBE_FWSTS 0x15F0C
#define IXGBE_CTRL_RST_MASK (IXGBE_CTRL_LNK_RST | IXGBE_CTRL_RST)
/* FACTPS */
+#define IXGBE_FACTPS_MNGCG 0x20000000 /* Manageblility Clock Gated */
#define IXGBE_FACTPS_LFS 0x40000000 /* LAN Function Select */
/* MHADD Bit Masks */
s32 (*set_fw_drv_ver)(struct ixgbe_hw *, u8, u8, u8, u8);
s32 (*get_thermal_sensor_data)(struct ixgbe_hw *);
s32 (*init_thermal_sensor_thresh)(struct ixgbe_hw *hw);
+ bool (*mng_fw_enabled)(struct ixgbe_hw *hw);
};
struct ixgbe_phy_operations {
bool adapter_stopped;
bool force_full_reset;
bool allow_unsupported_sfp;
+ bool mng_fw_enabled;
};
struct ixgbe_info {