diff options
-rw-r--r-- | drivers/net/bnx2.c | 52 | ||||
-rw-r--r-- | drivers/net/bnx2.h | 6 |
2 files changed, 45 insertions, 13 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 635a5856102b..015ff7906601 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -806,7 +806,19 @@ bnx2_setup_serdes_phy(struct bnx2 *bp) | |||
806 | bnx2_write_phy(bp, MII_ADVERTISE, new_adv); | 806 | bnx2_write_phy(bp, MII_ADVERTISE, new_adv); |
807 | bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | | 807 | bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | |
808 | BMCR_ANENABLE); | 808 | BMCR_ANENABLE); |
809 | bp->serdes_an_pending = SERDES_AN_TIMEOUT / bp->timer_interval; | 809 | if (CHIP_NUM(bp) == CHIP_NUM_5706) { |
810 | /* Speed up link-up time when the link partner | ||
811 | * does not autonegotiate which is very common | ||
812 | * in blade servers. Some blade servers use | ||
813 | * IPMI for kerboard input and it's important | ||
814 | * to minimize link disruptions. Autoneg. involves | ||
815 | * exchanging base pages plus 3 next pages and | ||
816 | * normally completes in about 120 msec. | ||
817 | */ | ||
818 | bp->current_interval = SERDES_AN_TIMEOUT; | ||
819 | bp->serdes_an_pending = 1; | ||
820 | mod_timer(&bp->timer, jiffies + bp->current_interval); | ||
821 | } | ||
810 | } | 822 | } |
811 | 823 | ||
812 | return 0; | 824 | return 0; |
@@ -3800,6 +3812,9 @@ bnx2_timer(unsigned long data) | |||
3800 | struct bnx2 *bp = (struct bnx2 *) data; | 3812 | struct bnx2 *bp = (struct bnx2 *) data; |
3801 | u32 msg; | 3813 | u32 msg; |
3802 | 3814 | ||
3815 | if (!netif_running(bp->dev)) | ||
3816 | return; | ||
3817 | |||
3803 | if (atomic_read(&bp->intr_sem) != 0) | 3818 | if (atomic_read(&bp->intr_sem) != 0) |
3804 | goto bnx2_restart_timer; | 3819 | goto bnx2_restart_timer; |
3805 | 3820 | ||
@@ -3817,6 +3832,8 @@ bnx2_timer(unsigned long data) | |||
3817 | else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) { | 3832 | else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) { |
3818 | u32 bmcr; | 3833 | u32 bmcr; |
3819 | 3834 | ||
3835 | bp->current_interval = bp->timer_interval; | ||
3836 | |||
3820 | bnx2_read_phy(bp, MII_BMCR, &bmcr); | 3837 | bnx2_read_phy(bp, MII_BMCR, &bmcr); |
3821 | 3838 | ||
3822 | if (bmcr & BMCR_ANENABLE) { | 3839 | if (bmcr & BMCR_ANENABLE) { |
@@ -3859,14 +3876,14 @@ bnx2_timer(unsigned long data) | |||
3859 | 3876 | ||
3860 | } | 3877 | } |
3861 | } | 3878 | } |
3879 | else | ||
3880 | bp->current_interval = bp->timer_interval; | ||
3862 | 3881 | ||
3863 | spin_unlock_irqrestore(&bp->phy_lock, flags); | 3882 | spin_unlock_irqrestore(&bp->phy_lock, flags); |
3864 | } | 3883 | } |
3865 | 3884 | ||
3866 | bnx2_restart_timer: | 3885 | bnx2_restart_timer: |
3867 | bp->timer.expires = RUN_AT(bp->timer_interval); | 3886 | mod_timer(&bp->timer, jiffies + bp->current_interval); |
3868 | |||
3869 | add_timer(&bp->timer); | ||
3870 | } | 3887 | } |
3871 | 3888 | ||
3872 | /* Called with rtnl_lock */ | 3889 | /* Called with rtnl_lock */ |
@@ -3919,12 +3936,7 @@ bnx2_open(struct net_device *dev) | |||
3919 | return rc; | 3936 | return rc; |
3920 | } | 3937 | } |
3921 | 3938 | ||
3922 | init_timer(&bp->timer); | 3939 | mod_timer(&bp->timer, jiffies + bp->current_interval); |
3923 | |||
3924 | bp->timer.expires = RUN_AT(bp->timer_interval); | ||
3925 | bp->timer.data = (unsigned long) bp; | ||
3926 | bp->timer.function = bnx2_timer; | ||
3927 | add_timer(&bp->timer); | ||
3928 | 3940 | ||
3929 | atomic_set(&bp->intr_sem, 0); | 3941 | atomic_set(&bp->intr_sem, 0); |
3930 | 3942 | ||
@@ -4485,8 +4497,9 @@ bnx2_nway_reset(struct net_device *dev) | |||
4485 | 4497 | ||
4486 | spin_lock_irq(&bp->phy_lock); | 4498 | spin_lock_irq(&bp->phy_lock); |
4487 | if (CHIP_NUM(bp) == CHIP_NUM_5706) { | 4499 | if (CHIP_NUM(bp) == CHIP_NUM_5706) { |
4488 | bp->serdes_an_pending = SERDES_AN_TIMEOUT / | 4500 | bp->current_interval = SERDES_AN_TIMEOUT; |
4489 | bp->timer_interval; | 4501 | bp->serdes_an_pending = 1; |
4502 | mod_timer(&bp->timer, jiffies + bp->current_interval); | ||
4490 | } | 4503 | } |
4491 | } | 4504 | } |
4492 | 4505 | ||
@@ -5315,6 +5328,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5315 | bp->stats_ticks = 1000000 & 0xffff00; | 5328 | bp->stats_ticks = 1000000 & 0xffff00; |
5316 | 5329 | ||
5317 | bp->timer_interval = HZ; | 5330 | bp->timer_interval = HZ; |
5331 | bp->current_interval = HZ; | ||
5318 | 5332 | ||
5319 | /* Disable WOL support if we are running on a SERDES chip. */ | 5333 | /* Disable WOL support if we are running on a SERDES chip. */ |
5320 | if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) { | 5334 | if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) { |
@@ -5338,6 +5352,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5338 | bp->req_line_speed = 0; | 5352 | bp->req_line_speed = 0; |
5339 | if (bp->phy_flags & PHY_SERDES_FLAG) { | 5353 | if (bp->phy_flags & PHY_SERDES_FLAG) { |
5340 | bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg; | 5354 | bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg; |
5355 | |||
5356 | reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + | ||
5357 | BNX2_PORT_HW_CFG_CONFIG); | ||
5358 | reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK; | ||
5359 | if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) { | ||
5360 | bp->autoneg = 0; | ||
5361 | bp->req_line_speed = bp->line_speed = SPEED_1000; | ||
5362 | bp->req_duplex = DUPLEX_FULL; | ||
5363 | } | ||
5341 | } | 5364 | } |
5342 | else { | 5365 | else { |
5343 | bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg; | 5366 | bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg; |
@@ -5345,6 +5368,11 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5345 | 5368 | ||
5346 | bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX; | 5369 | bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX; |
5347 | 5370 | ||
5371 | init_timer(&bp->timer); | ||
5372 | bp->timer.expires = RUN_AT(bp->timer_interval); | ||
5373 | bp->timer.data = (unsigned long) bp; | ||
5374 | bp->timer.function = bnx2_timer; | ||
5375 | |||
5348 | return 0; | 5376 | return 0; |
5349 | 5377 | ||
5350 | err_out_unmap: | 5378 | err_out_unmap: |
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 63b94ca0018b..e1fb099acbf2 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h | |||
@@ -3872,6 +3872,7 @@ struct bnx2 { | |||
3872 | char *name; | 3872 | char *name; |
3873 | 3873 | ||
3874 | int timer_interval; | 3874 | int timer_interval; |
3875 | int current_interval; | ||
3875 | struct timer_list timer; | 3876 | struct timer_list timer; |
3876 | struct work_struct reset_task; | 3877 | struct work_struct reset_task; |
3877 | int in_reset_task; | 3878 | int in_reset_task; |
@@ -3986,7 +3987,7 @@ struct bnx2 { | |||
3986 | #define PHY_LOOPBACK 2 | 3987 | #define PHY_LOOPBACK 2 |
3987 | 3988 | ||
3988 | u8 serdes_an_pending; | 3989 | u8 serdes_an_pending; |
3989 | #define SERDES_AN_TIMEOUT (2 * HZ) | 3990 | #define SERDES_AN_TIMEOUT (HZ / 3) |
3990 | 3991 | ||
3991 | u8 mac_addr[8]; | 3992 | u8 mac_addr[8]; |
3992 | 3993 | ||
@@ -4172,6 +4173,9 @@ struct fw_info { | |||
4172 | 4173 | ||
4173 | #define BNX2_PORT_HW_CFG_MAC_LOWER 0x00000054 | 4174 | #define BNX2_PORT_HW_CFG_MAC_LOWER 0x00000054 |
4174 | #define BNX2_PORT_HW_CFG_CONFIG 0x00000058 | 4175 | #define BNX2_PORT_HW_CFG_CONFIG 0x00000058 |
4176 | #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK 0x001f0000 | ||
4177 | #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_AN 0x00000000 | ||
4178 | #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G 0x00030000 | ||
4175 | 4179 | ||
4176 | #define BNX2_PORT_HW_CFG_IMD_MAC_A_UPPER 0x00000068 | 4180 | #define BNX2_PORT_HW_CFG_IMD_MAC_A_UPPER 0x00000068 |
4177 | #define BNX2_PORT_HW_CFG_IMD_MAC_A_LOWER 0x0000006c | 4181 | #define BNX2_PORT_HW_CFG_IMD_MAC_A_LOWER 0x0000006c |