aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorPeter Waskiewicz <peter.p.waskiewicz.jr@intel.com>2010-04-26 20:38:15 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-27 13:18:25 -0400
commit61fac744dddb22d99c7b12250bc9bada7866df08 (patch)
treec0d0502495cdc8fc2ade8ce44e5f483835c6e7b5 /drivers/net
parent908ba2bfd22253f26fa910cd855e4ccffb1467d0 (diff)
ixgbe: Power down PHY during driver resets
The PHY laser is still on during driver init. It's allowing garbage to hit our FIFO, which eventually can cause the entire device to die. Power down the laser while setting up the device, and re-enable the laser before getting link. 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')
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c62
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c22
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h2
3 files changed, 62 insertions, 24 deletions
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index b405a00817c6..12fc0e7ba2ca 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -39,6 +39,8 @@
39#define IXGBE_82599_MC_TBL_SIZE 128 39#define IXGBE_82599_MC_TBL_SIZE 128
40#define IXGBE_82599_VFT_TBL_SIZE 128 40#define IXGBE_82599_VFT_TBL_SIZE 128
41 41
42void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
43void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
42void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); 44void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
43s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, 45s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
44 ixgbe_link_speed speed, 46 ixgbe_link_speed speed,
@@ -69,8 +71,14 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
69 if (hw->phy.multispeed_fiber) { 71 if (hw->phy.multispeed_fiber) {
70 /* Set up dual speed SFP+ support */ 72 /* Set up dual speed SFP+ support */
71 mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber; 73 mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber;
74 mac->ops.disable_tx_laser =
75 &ixgbe_disable_tx_laser_multispeed_fiber;
76 mac->ops.enable_tx_laser =
77 &ixgbe_enable_tx_laser_multispeed_fiber;
72 mac->ops.flap_tx_laser = &ixgbe_flap_tx_laser_multispeed_fiber; 78 mac->ops.flap_tx_laser = &ixgbe_flap_tx_laser_multispeed_fiber;
73 } else { 79 } else {
80 mac->ops.disable_tx_laser = NULL;
81 mac->ops.enable_tx_laser = NULL;
74 mac->ops.flap_tx_laser = NULL; 82 mac->ops.flap_tx_laser = NULL;
75 if ((mac->ops.get_media_type(hw) == 83 if ((mac->ops.get_media_type(hw) ==
76 ixgbe_media_type_backplane) && 84 ixgbe_media_type_backplane) &&
@@ -415,6 +423,44 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
415 return status; 423 return status;
416} 424}
417 425
426 /**
427 * ixgbe_disable_tx_laser_multispeed_fiber - Disable Tx laser
428 * @hw: pointer to hardware structure
429 *
430 * The base drivers may require better control over SFP+ module
431 * PHY states. This includes selectively shutting down the Tx
432 * laser on the PHY, effectively halting physical link.
433 **/
434void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
435{
436 u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
437
438 /* Disable tx laser; allow 100us to go dark per spec */
439 esdp_reg |= IXGBE_ESDP_SDP3;
440 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
441 IXGBE_WRITE_FLUSH(hw);
442 udelay(100);
443}
444
445/**
446 * ixgbe_enable_tx_laser_multispeed_fiber - Enable Tx laser
447 * @hw: pointer to hardware structure
448 *
449 * The base drivers may require better control over SFP+ module
450 * PHY states. This includes selectively turning on the Tx
451 * laser on the PHY, effectively starting physical link.
452 **/
453void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
454{
455 u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
456
457 /* Enable tx laser; allow 100ms to light up */
458 esdp_reg &= ~IXGBE_ESDP_SDP3;
459 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
460 IXGBE_WRITE_FLUSH(hw);
461 msleep(100);
462}
463
418/** 464/**
419 * ixgbe_flap_tx_laser_multispeed_fiber - Flap Tx laser 465 * ixgbe_flap_tx_laser_multispeed_fiber - Flap Tx laser
420 * @hw: pointer to hardware structure 466 * @hw: pointer to hardware structure
@@ -429,23 +475,11 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
429 **/ 475 **/
430void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) 476void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
431{ 477{
432 u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
433
434 hw_dbg(hw, "ixgbe_flap_tx_laser_multispeed_fiber\n"); 478 hw_dbg(hw, "ixgbe_flap_tx_laser_multispeed_fiber\n");
435 479
436 if (hw->mac.autotry_restart) { 480 if (hw->mac.autotry_restart) {
437 /* Disable tx laser; allow 100us to go dark per spec */ 481 ixgbe_disable_tx_laser_multispeed_fiber(hw);
438 esdp_reg |= IXGBE_ESDP_SDP3; 482 ixgbe_enable_tx_laser_multispeed_fiber(hw);
439 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
440 IXGBE_WRITE_FLUSH(hw);
441 udelay(100);
442
443 /* Enable tx laser; allow 100ms to light up */
444 esdp_reg &= ~IXGBE_ESDP_SDP3;
445 IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
446 IXGBE_WRITE_FLUSH(hw);
447 msleep(100);
448
449 hw->mac.autotry_restart = false; 483 hw->mac.autotry_restart = false;
450 } 484 }
451} 485}
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 8f677cb86290..6c00ee493a3b 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -2982,6 +2982,10 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
2982 else 2982 else
2983 ixgbe_configure_msi_and_legacy(adapter); 2983 ixgbe_configure_msi_and_legacy(adapter);
2984 2984
2985 /* enable the optics */
2986 if (hw->phy.multispeed_fiber)
2987 hw->mac.ops.enable_tx_laser(hw);
2988
2985 clear_bit(__IXGBE_DOWN, &adapter->state); 2989 clear_bit(__IXGBE_DOWN, &adapter->state);
2986 ixgbe_napi_enable_all(adapter); 2990 ixgbe_napi_enable_all(adapter);
2987 2991
@@ -3243,6 +3247,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
3243 /* signal that we are down to the interrupt handler */ 3247 /* signal that we are down to the interrupt handler */
3244 set_bit(__IXGBE_DOWN, &adapter->state); 3248 set_bit(__IXGBE_DOWN, &adapter->state);
3245 3249
3250 /* power down the optics */
3251 if (hw->phy.multispeed_fiber)
3252 hw->mac.ops.disable_tx_laser(hw);
3253
3246 /* disable receive for all VFs and wait one second */ 3254 /* disable receive for all VFs and wait one second */
3247 if (adapter->num_vfs) { 3255 if (adapter->num_vfs) {
3248 /* ping all the active vfs to let them know we are going down */ 3256 /* ping all the active vfs to let them know we are going down */
@@ -6253,6 +6261,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
6253 goto err_eeprom; 6261 goto err_eeprom;
6254 } 6262 }
6255 6263
6264 /* power down the optics */
6265 if (hw->phy.multispeed_fiber)
6266 hw->mac.ops.disable_tx_laser(hw);
6267
6256 init_timer(&adapter->watchdog_timer); 6268 init_timer(&adapter->watchdog_timer);
6257 adapter->watchdog_timer.function = &ixgbe_watchdog; 6269 adapter->watchdog_timer.function = &ixgbe_watchdog;
6258 adapter->watchdog_timer.data = (unsigned long)adapter; 6270 adapter->watchdog_timer.data = (unsigned long)adapter;
@@ -6400,16 +6412,6 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
6400 del_timer_sync(&adapter->sfp_timer); 6412 del_timer_sync(&adapter->sfp_timer);
6401 cancel_work_sync(&adapter->watchdog_task); 6413 cancel_work_sync(&adapter->watchdog_task);
6402 cancel_work_sync(&adapter->sfp_task); 6414 cancel_work_sync(&adapter->sfp_task);
6403 if (adapter->hw.phy.multispeed_fiber) {
6404 struct ixgbe_hw *hw = &adapter->hw;
6405 /*
6406 * Restart clause 37 autoneg, disable and re-enable
6407 * the tx laser, to clear & alert the link partner
6408 * that it needs to restart autotry
6409 */
6410 hw->mac.autotry_restart = true;
6411 hw->mac.ops.flap_tx_laser(hw);
6412 }
6413 cancel_work_sync(&adapter->multispeed_fiber_task); 6415 cancel_work_sync(&adapter->multispeed_fiber_task);
6414 cancel_work_sync(&adapter->sfp_config_module_task); 6416 cancel_work_sync(&adapter->sfp_config_module_task);
6415 if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || 6417 if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 4ec6dc1a5b75..534affcc38ca 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -2398,6 +2398,8 @@ struct ixgbe_mac_operations {
2398 s32 (*enable_rx_dma)(struct ixgbe_hw *, u32); 2398 s32 (*enable_rx_dma)(struct ixgbe_hw *, u32);
2399 2399
2400 /* Link */ 2400 /* Link */
2401 void (*disable_tx_laser)(struct ixgbe_hw *);
2402 void (*enable_tx_laser)(struct ixgbe_hw *);
2401 void (*flap_tx_laser)(struct ixgbe_hw *); 2403 void (*flap_tx_laser)(struct ixgbe_hw *);
2402 s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool); 2404 s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool);
2403 s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool); 2405 s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool);