diff options
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r-- | drivers/net/bnx2.c | 111 |
1 files changed, 55 insertions, 56 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 9b391cf80a32..78974810e307 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -4173,81 +4173,80 @@ bnx2_test_intr(struct bnx2 *bp) | |||
4173 | } | 4173 | } |
4174 | 4174 | ||
4175 | static void | 4175 | static void |
4176 | bnx2_timer(unsigned long data) | 4176 | bnx2_5706_serdes_timer(struct bnx2 *bp) |
4177 | { | 4177 | { |
4178 | struct bnx2 *bp = (struct bnx2 *) data; | 4178 | spin_lock(&bp->phy_lock); |
4179 | u32 msg; | 4179 | if (bp->serdes_an_pending) |
4180 | bp->serdes_an_pending--; | ||
4181 | else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) { | ||
4182 | u32 bmcr; | ||
4180 | 4183 | ||
4181 | if (!netif_running(bp->dev)) | 4184 | bp->current_interval = bp->timer_interval; |
4182 | return; | ||
4183 | 4185 | ||
4184 | if (atomic_read(&bp->intr_sem) != 0) | 4186 | bnx2_read_phy(bp, MII_BMCR, &bmcr); |
4185 | goto bnx2_restart_timer; | ||
4186 | 4187 | ||
4187 | msg = (u32) ++bp->fw_drv_pulse_wr_seq; | 4188 | if (bmcr & BMCR_ANENABLE) { |
4188 | REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg); | 4189 | u32 phy1, phy2; |
4189 | 4190 | ||
4190 | bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT); | 4191 | bnx2_write_phy(bp, 0x1c, 0x7c00); |
4192 | bnx2_read_phy(bp, 0x1c, &phy1); | ||
4191 | 4193 | ||
4192 | if ((bp->phy_flags & PHY_SERDES_FLAG) && | 4194 | bnx2_write_phy(bp, 0x17, 0x0f01); |
4193 | (CHIP_NUM(bp) == CHIP_NUM_5706)) { | 4195 | bnx2_read_phy(bp, 0x15, &phy2); |
4196 | bnx2_write_phy(bp, 0x17, 0x0f01); | ||
4197 | bnx2_read_phy(bp, 0x15, &phy2); | ||
4194 | 4198 | ||
4195 | spin_lock(&bp->phy_lock); | 4199 | if ((phy1 & 0x10) && /* SIGNAL DETECT */ |
4196 | if (bp->serdes_an_pending) { | 4200 | !(phy2 & 0x20)) { /* no CONFIG */ |
4197 | bp->serdes_an_pending--; | 4201 | |
4202 | bmcr &= ~BMCR_ANENABLE; | ||
4203 | bmcr |= BMCR_SPEED1000 | BMCR_FULLDPLX; | ||
4204 | bnx2_write_phy(bp, MII_BMCR, bmcr); | ||
4205 | bp->phy_flags |= PHY_PARALLEL_DETECT_FLAG; | ||
4206 | } | ||
4198 | } | 4207 | } |
4199 | else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) { | 4208 | } |
4200 | u32 bmcr; | 4209 | else if ((bp->link_up) && (bp->autoneg & AUTONEG_SPEED) && |
4210 | (bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)) { | ||
4211 | u32 phy2; | ||
4201 | 4212 | ||
4202 | bp->current_interval = bp->timer_interval; | 4213 | bnx2_write_phy(bp, 0x17, 0x0f01); |
4214 | bnx2_read_phy(bp, 0x15, &phy2); | ||
4215 | if (phy2 & 0x20) { | ||
4216 | u32 bmcr; | ||
4203 | 4217 | ||
4204 | bnx2_read_phy(bp, MII_BMCR, &bmcr); | 4218 | bnx2_read_phy(bp, MII_BMCR, &bmcr); |
4219 | bmcr |= BMCR_ANENABLE; | ||
4220 | bnx2_write_phy(bp, MII_BMCR, bmcr); | ||
4205 | 4221 | ||
4206 | if (bmcr & BMCR_ANENABLE) { | 4222 | bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; |
4207 | u32 phy1, phy2; | 4223 | } |
4208 | 4224 | } else | |
4209 | bnx2_write_phy(bp, 0x1c, 0x7c00); | 4225 | bp->current_interval = bp->timer_interval; |
4210 | bnx2_read_phy(bp, 0x1c, &phy1); | ||
4211 | |||
4212 | bnx2_write_phy(bp, 0x17, 0x0f01); | ||
4213 | bnx2_read_phy(bp, 0x15, &phy2); | ||
4214 | bnx2_write_phy(bp, 0x17, 0x0f01); | ||
4215 | bnx2_read_phy(bp, 0x15, &phy2); | ||
4216 | 4226 | ||
4217 | if ((phy1 & 0x10) && /* SIGNAL DETECT */ | 4227 | spin_unlock(&bp->phy_lock); |
4218 | !(phy2 & 0x20)) { /* no CONFIG */ | 4228 | } |
4219 | 4229 | ||
4220 | bmcr &= ~BMCR_ANENABLE; | 4230 | static void |
4221 | bmcr |= BMCR_SPEED1000 | | 4231 | bnx2_timer(unsigned long data) |
4222 | BMCR_FULLDPLX; | 4232 | { |
4223 | bnx2_write_phy(bp, MII_BMCR, bmcr); | 4233 | struct bnx2 *bp = (struct bnx2 *) data; |
4224 | bp->phy_flags |= | 4234 | u32 msg; |
4225 | PHY_PARALLEL_DETECT_FLAG; | ||
4226 | } | ||
4227 | } | ||
4228 | } | ||
4229 | else if ((bp->link_up) && (bp->autoneg & AUTONEG_SPEED) && | ||
4230 | (bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)) { | ||
4231 | u32 phy2; | ||
4232 | 4235 | ||
4233 | bnx2_write_phy(bp, 0x17, 0x0f01); | 4236 | if (!netif_running(bp->dev)) |
4234 | bnx2_read_phy(bp, 0x15, &phy2); | 4237 | return; |
4235 | if (phy2 & 0x20) { | ||
4236 | u32 bmcr; | ||
4237 | 4238 | ||
4238 | bnx2_read_phy(bp, MII_BMCR, &bmcr); | 4239 | if (atomic_read(&bp->intr_sem) != 0) |
4239 | bmcr |= BMCR_ANENABLE; | 4240 | goto bnx2_restart_timer; |
4240 | bnx2_write_phy(bp, MII_BMCR, bmcr); | ||
4241 | 4241 | ||
4242 | bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; | 4242 | msg = (u32) ++bp->fw_drv_pulse_wr_seq; |
4243 | REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg); | ||
4243 | 4244 | ||
4244 | } | 4245 | bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT); |
4245 | } | ||
4246 | else | ||
4247 | bp->current_interval = bp->timer_interval; | ||
4248 | 4246 | ||
4249 | spin_unlock(&bp->phy_lock); | 4247 | if ((bp->phy_flags & PHY_SERDES_FLAG) && |
4250 | } | 4248 | (CHIP_NUM(bp) == CHIP_NUM_5706)) |
4249 | bnx2_5706_serdes_timer(bp); | ||
4251 | 4250 | ||
4252 | bnx2_restart_timer: | 4251 | bnx2_restart_timer: |
4253 | mod_timer(&bp->timer, jiffies + bp->current_interval); | 4252 | mod_timer(&bp->timer, jiffies + bp->current_interval); |