Skip to content

Commit

Permalink
ixgbe: fix MNG FW support when adapter not up
Browse files Browse the repository at this point in the history
We were only turning the laser on when the adapter was up.  This
causes issues for those who wanted to access the MNG FW while the
port was in a down state.  This patch makes sure the laser is turned
on in probe and remain up even after the port is brought down.

Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  • Loading branch information
Don Skidmore authored and Jeff Kirsher committed Apr 18, 2013
1 parent b8e8200 commit 0b2679d
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 5 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
Original file line number Diff line number Diff line change
Expand Up @@ -1305,6 +1305,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
.release_swfw_sync = &ixgbe_release_swfw_sync,
.get_thermal_sensor_data = NULL,
.init_thermal_sensor_thresh = NULL,
.mng_fw_enabled = NULL,
};

static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
Expand Down
48 changes: 43 additions & 5 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,34 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
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 =
Expand Down Expand Up @@ -563,7 +585,8 @@ static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
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,
Expand Down Expand Up @@ -615,7 +638,8 @@ static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
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);
Expand Down Expand Up @@ -933,6 +957,7 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
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 */
Expand Down Expand Up @@ -964,6 +989,9 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
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.
Expand Down Expand Up @@ -1019,6 +1047,16 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
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
Expand Down Expand Up @@ -2216,7 +2254,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
.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 = {
Expand Down
10 changes: 10 additions & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7370,6 +7370,10 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
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:
Expand Down Expand Up @@ -7623,6 +7627,12 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
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:
Expand Down
10 changes: 10 additions & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,13 @@ struct ixgbe_thermal_sensor_data {
#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
Expand Down Expand Up @@ -1019,6 +1026,7 @@ struct ixgbe_thermal_sensor_data {
#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 */
Expand Down Expand Up @@ -2861,6 +2869,7 @@ struct ixgbe_mac_operations {
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 {
Expand Down Expand Up @@ -2988,6 +2997,7 @@ struct ixgbe_hw {
bool adapter_stopped;
bool force_full_reset;
bool allow_unsupported_sfp;
bool mng_fw_enabled;
};

struct ixgbe_info {
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,7 @@ static struct ixgbe_mac_operations mac_ops_X540 = {
.enable_rx_buff = &ixgbe_enable_rx_buff_generic,
.get_thermal_sensor_data = NULL,
.init_thermal_sensor_thresh = NULL,
.mng_fw_enabled = NULL,
};

static struct ixgbe_eeprom_operations eeprom_ops_X540 = {
Expand Down

0 comments on commit 0b2679d

Please sign in to comment.