diff options
author | Don Skidmore <donald.c.skidmore@intel.com> | 2009-05-26 23:40:47 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-05-26 23:40:47 -0400 |
commit | 8ca783ab78e3fa518885c4fef93d0972e450a4de (patch) | |
tree | c27b8e00c7114ea68483226898fa60c41227828c /drivers/net/ixgbe | |
parent | f7c86a3252af7f1222f9ebce66f3654ad3aa9ff0 (diff) |
ixgbe: fix 82598 SFP initialization after driver load.
If we loaded the driver with out a SFP module plugged in it would
leave it in a state that make it later unable to link when a module
was plugged in. This patch corrects that by:
ixgbe_probe() - moving the check for IXGBE_ERR_SFP_NOT_PRESENT from
after get_invariants() to after reset_hw() as now reset_hw() is
where this condition will be indentified.
ixgbe_reset_hw_82598() - Enable this function to now return
IXGBE_ERR_SFP_NOT_PRESENT.
ixgbe_identify_sfp_module_generic() - This where the lack of SFP
module is detected. Modifications are added to allow a different
return value for modules that just haven't been plugged in yet.
Other functions were updated to allow correct logging.
Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ixgbe')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_82598.c | 12 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 33 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_phy.c | 13 |
3 files changed, 39 insertions, 19 deletions
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index afc9fe3f1eda..88e8350aa786 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c | |||
@@ -698,6 +698,7 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, | |||
698 | static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) | 698 | static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) |
699 | { | 699 | { |
700 | s32 status = 0; | 700 | s32 status = 0; |
701 | s32 phy_status = 0; | ||
701 | u32 ctrl; | 702 | u32 ctrl; |
702 | u32 gheccr; | 703 | u32 gheccr; |
703 | u32 i; | 704 | u32 i; |
@@ -745,13 +746,17 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) | |||
745 | /* PHY ops must be identified and initialized prior to reset */ | 746 | /* PHY ops must be identified and initialized prior to reset */ |
746 | 747 | ||
747 | /* Init PHY and function pointers, perform SFP setup */ | 748 | /* Init PHY and function pointers, perform SFP setup */ |
748 | status = hw->phy.ops.init(hw); | 749 | phy_status = hw->phy.ops.init(hw); |
749 | if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) | 750 | if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED) |
750 | goto reset_hw_out; | 751 | goto reset_hw_out; |
752 | else if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT) | ||
753 | goto no_phy_reset; | ||
754 | |||
751 | 755 | ||
752 | hw->phy.ops.reset(hw); | 756 | hw->phy.ops.reset(hw); |
753 | } | 757 | } |
754 | 758 | ||
759 | no_phy_reset: | ||
755 | /* | 760 | /* |
756 | * Prevent the PCI-E bus from from hanging by disabling PCI-E master | 761 | * Prevent the PCI-E bus from from hanging by disabling PCI-E master |
757 | * access and verify no pending requests before reset | 762 | * access and verify no pending requests before reset |
@@ -811,6 +816,9 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) | |||
811 | hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); | 816 | hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); |
812 | 817 | ||
813 | reset_hw_out: | 818 | reset_hw_out: |
819 | if (phy_status) | ||
820 | status = phy_status; | ||
821 | |||
814 | return status; | 822 | return status; |
815 | } | 823 | } |
816 | 824 | ||
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index e52798c4816b..f9223acae30b 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -2599,7 +2599,10 @@ int ixgbe_up(struct ixgbe_adapter *adapter) | |||
2599 | void ixgbe_reset(struct ixgbe_adapter *adapter) | 2599 | void ixgbe_reset(struct ixgbe_adapter *adapter) |
2600 | { | 2600 | { |
2601 | struct ixgbe_hw *hw = &adapter->hw; | 2601 | struct ixgbe_hw *hw = &adapter->hw; |
2602 | if (hw->mac.ops.init_hw(hw)) | 2602 | int err; |
2603 | |||
2604 | err = hw->mac.ops.init_hw(hw); | ||
2605 | if (err && (err != IXGBE_ERR_SFP_NOT_PRESENT)) | ||
2603 | dev_err(&adapter->pdev->dev, "Hardware Error\n"); | 2606 | dev_err(&adapter->pdev->dev, "Hardware Error\n"); |
2604 | 2607 | ||
2605 | /* reprogram the RAR[0] in case user changed it. */ | 2608 | /* reprogram the RAR[0] in case user changed it. */ |
@@ -5167,20 +5170,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
5167 | INIT_WORK(&adapter->sfp_config_module_task, | 5170 | INIT_WORK(&adapter->sfp_config_module_task, |
5168 | ixgbe_sfp_config_module_task); | 5171 | ixgbe_sfp_config_module_task); |
5169 | 5172 | ||
5170 | err = ii->get_invariants(hw); | 5173 | ii->get_invariants(hw); |
5171 | if (err == IXGBE_ERR_SFP_NOT_PRESENT) { | ||
5172 | /* start a kernel thread to watch for a module to arrive */ | ||
5173 | set_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state); | ||
5174 | mod_timer(&adapter->sfp_timer, | ||
5175 | round_jiffies(jiffies + (2 * HZ))); | ||
5176 | err = 0; | ||
5177 | } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { | ||
5178 | DPRINTK(PROBE, ERR, "failed to load because an " | ||
5179 | "unsupported SFP+ module type was detected.\n"); | ||
5180 | goto err_hw_init; | ||
5181 | } else if (err) { | ||
5182 | goto err_hw_init; | ||
5183 | } | ||
5184 | 5174 | ||
5185 | /* setup the private structure */ | 5175 | /* setup the private structure */ |
5186 | err = ixgbe_sw_init(adapter); | 5176 | err = ixgbe_sw_init(adapter); |
@@ -5200,7 +5190,18 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
5200 | 5190 | ||
5201 | /* reset_hw fills in the perm_addr as well */ | 5191 | /* reset_hw fills in the perm_addr as well */ |
5202 | err = hw->mac.ops.reset_hw(hw); | 5192 | err = hw->mac.ops.reset_hw(hw); |
5203 | if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { | 5193 | if (err == IXGBE_ERR_SFP_NOT_PRESENT && |
5194 | hw->mac.type == ixgbe_mac_82598EB) { | ||
5195 | /* | ||
5196 | * Start a kernel thread to watch for a module to arrive. | ||
5197 | * Only do this for 82598, since 82599 will generate | ||
5198 | * interrupts on module arrival. | ||
5199 | */ | ||
5200 | set_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state); | ||
5201 | mod_timer(&adapter->sfp_timer, | ||
5202 | round_jiffies(jiffies + (2 * HZ))); | ||
5203 | err = 0; | ||
5204 | } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { | ||
5204 | dev_err(&adapter->pdev->dev, "failed to load because an " | 5205 | dev_err(&adapter->pdev->dev, "failed to load because an " |
5205 | "unsupported SFP+ module type was detected.\n"); | 5206 | "unsupported SFP+ module type was detected.\n"); |
5206 | goto err_sw_init; | 5207 | goto err_sw_init; |
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 8210b49aeff4..e43d6248d7d4 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c | |||
@@ -530,11 +530,22 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) | |||
530 | u8 cable_tech = 0; | 530 | u8 cable_tech = 0; |
531 | u16 enforce_sfp = 0; | 531 | u16 enforce_sfp = 0; |
532 | 532 | ||
533 | if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber) { | ||
534 | hw->phy.sfp_type = ixgbe_sfp_type_not_present; | ||
535 | status = IXGBE_ERR_SFP_NOT_PRESENT; | ||
536 | goto out; | ||
537 | } | ||
538 | |||
533 | status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER, | 539 | status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER, |
534 | &identifier); | 540 | &identifier); |
535 | 541 | ||
536 | if (status == IXGBE_ERR_SFP_NOT_PRESENT) { | 542 | if (status == IXGBE_ERR_SFP_NOT_PRESENT || status == IXGBE_ERR_I2C) { |
543 | status = IXGBE_ERR_SFP_NOT_PRESENT; | ||
537 | hw->phy.sfp_type = ixgbe_sfp_type_not_present; | 544 | hw->phy.sfp_type = ixgbe_sfp_type_not_present; |
545 | if (hw->phy.type != ixgbe_phy_nl) { | ||
546 | hw->phy.id = 0; | ||
547 | hw->phy.type = ixgbe_phy_unknown; | ||
548 | } | ||
538 | goto out; | 549 | goto out; |
539 | } | 550 | } |
540 | 551 | ||