aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe
diff options
context:
space:
mode:
authorDon Skidmore <donald.c.skidmore@intel.com>2009-05-26 23:40:47 -0400
committerDavid S. Miller <davem@davemloft.net>2009-05-26 23:40:47 -0400
commit8ca783ab78e3fa518885c4fef93d0972e450a4de (patch)
treec27b8e00c7114ea68483226898fa60c41227828c /drivers/net/ixgbe
parentf7c86a3252af7f1222f9ebce66f3654ad3aa9ff0 (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.c12
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c33
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.c13
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,
698static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) 698static 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
759no_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
813reset_hw_out: 818reset_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)
2599void ixgbe_reset(struct ixgbe_adapter *adapter) 2599void 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