diff options
| author | Stephen Hemminger <shemminger@linux-foundation.org> | 2008-02-22 19:00:33 -0500 |
|---|---|---|
| committer | Jeff Garzik <jeff@garzik.org> | 2008-02-24 00:07:39 -0500 |
| commit | a84d0a3d6909c871bfa617a45a7517ce9292d4fb (patch) | |
| tree | a137bb82a4746a66f5bb7a33829b454e83026392 /drivers/net/sky2.c | |
| parent | f11cf25ef345a320b152aa68a014c8a65cf4ed44 (diff) | |
sky2: fix LED management
Fix problems in LED management, so ethtool -p works correctly on Yukon-EC
and other chips. The driver was incorrectly setting the PHY LED overide bits.
Moral: read the spec sheet, not the vendor driver.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/sky2.c')
| -rw-r--r-- | drivers/net/sky2.c | 123 |
1 files changed, 61 insertions, 62 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 9a6295909e4..54c662690f6 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
| @@ -572,8 +572,9 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
| 572 | default: | 572 | default: |
| 573 | /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ | 573 | /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ |
| 574 | ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL; | 574 | ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL; |
| 575 | |||
| 575 | /* turn off the Rx LED (LED_RX) */ | 576 | /* turn off the Rx LED (LED_RX) */ |
| 576 | ledover &= ~PHY_M_LED_MO_RX; | 577 | ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); |
| 577 | } | 578 | } |
| 578 | 579 | ||
| 579 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && | 580 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && |
| @@ -602,7 +603,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
| 602 | 603 | ||
| 603 | if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { | 604 | if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { |
| 604 | /* turn on 100 Mbps LED (LED_LINK100) */ | 605 | /* turn on 100 Mbps LED (LED_LINK100) */ |
| 605 | ledover |= PHY_M_LED_MO_100; | 606 | ledover |= PHY_M_LED_MO_100(MO_LED_ON); |
| 606 | } | 607 | } |
| 607 | 608 | ||
| 608 | if (ledover) | 609 | if (ledover) |
| @@ -3322,82 +3323,80 @@ static void sky2_set_multicast(struct net_device *dev) | |||
| 3322 | /* Can have one global because blinking is controlled by | 3323 | /* Can have one global because blinking is controlled by |
| 3323 | * ethtool and that is always under RTNL mutex | 3324 | * ethtool and that is always under RTNL mutex |
| 3324 | */ | 3325 | */ |
| 3325 | static void sky2_led(struct sky2_hw *hw, unsigned port, int on) | 3326 | static void sky2_led(struct sky2_port *sky2, enum led_mode mode) |
| 3326 | { | 3327 | { |
| 3327 | u16 pg; | 3328 | struct sky2_hw *hw = sky2->hw; |
| 3329 | unsigned port = sky2->port; | ||
| 3328 | 3330 | ||
| 3329 | switch (hw->chip_id) { | 3331 | spin_lock_bh(&sky2->phy_lock); |
| 3330 | case CHIP_ID_YUKON_XL: | 3332 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || |
| 3333 | hw->chip_id == CHIP_ID_YUKON_EX || | ||
| 3334 | hw->chip_id == CHIP_ID_YUKON_SUPR) { | ||
| 3335 | u16 pg; | ||
| 3331 | pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); | 3336 | pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
| 3332 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); | 3337 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); |
| 3333 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, | ||
| 3334 | on ? (PHY_M_LEDC_LOS_CTRL(1) | | ||
| 3335 | PHY_M_LEDC_INIT_CTRL(7) | | ||
| 3336 | PHY_M_LEDC_STA1_CTRL(7) | | ||
| 3337 | PHY_M_LEDC_STA0_CTRL(7)) | ||
| 3338 | : 0); | ||
| 3339 | 3338 | ||
| 3340 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); | 3339 | switch (mode) { |
| 3341 | break; | 3340 | case MO_LED_OFF: |
| 3341 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, | ||
| 3342 | PHY_M_LEDC_LOS_CTRL(8) | | ||
| 3343 | PHY_M_LEDC_INIT_CTRL(8) | | ||
| 3344 | PHY_M_LEDC_STA1_CTRL(8) | | ||
| 3345 | PHY_M_LEDC_STA0_CTRL(8)); | ||
| 3346 | break; | ||
| 3347 | case MO_LED_ON: | ||
| 3348 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, | ||
| 3349 | PHY_M_LEDC_LOS_CTRL(9) | | ||
| 3350 | PHY_M_LEDC_INIT_CTRL(9) | | ||
| 3351 | PHY_M_LEDC_STA1_CTRL(9) | | ||
| 3352 | PHY_M_LEDC_STA0_CTRL(9)); | ||
| 3353 | break; | ||
| 3354 | case MO_LED_BLINK: | ||
| 3355 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, | ||
| 3356 | PHY_M_LEDC_LOS_CTRL(0xa) | | ||
| 3357 | PHY_M_LEDC_INIT_CTRL(0xa) | | ||
| 3358 | PHY_M_LEDC_STA1_CTRL(0xa) | | ||
| 3359 | PHY_M_LEDC_STA0_CTRL(0xa)); | ||
| 3360 | break; | ||
| 3361 | case MO_LED_NORM: | ||
| 3362 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, | ||
| 3363 | PHY_M_LEDC_LOS_CTRL(1) | | ||
| 3364 | PHY_M_LEDC_INIT_CTRL(8) | | ||
| 3365 | PHY_M_LEDC_STA1_CTRL(7) | | ||
| 3366 | PHY_M_LEDC_STA0_CTRL(7)); | ||
| 3367 | } | ||
| 3342 | 3368 | ||
| 3343 | default: | 3369 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); |
| 3344 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); | 3370 | } else |
| 3345 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, | 3371 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, |
| 3346 | on ? PHY_M_LED_ALL : 0); | 3372 | PHY_M_LED_MO_DUP(mode) | |
| 3347 | } | 3373 | PHY_M_LED_MO_10(mode) | |
| 3374 | PHY_M_LED_MO_100(mode) | | ||
| 3375 | PHY_M_LED_MO_1000(mode) | | ||
| 3376 | PHY_M_LED_MO_RX(mode) | | ||
| 3377 | PHY_M_LED_MO_TX(mode)); | ||
| 3378 | |||
| 3379 | spin_unlock_bh(&sky2->phy_lock); | ||
| 3348 | } | 3380 | } |
| 3349 | 3381 | ||
| 3350 | /* blink LED's for finding board */ | 3382 | /* blink LED's for finding board */ |
| 3351 | static int sky2_phys_id(struct net_device *dev, u32 data) | 3383 | static int sky2_phys_id(struct net_device *dev, u32 data) |
| 3352 | { | 3384 | { |
| 3353 | struct sky2_port *sky2 = netdev_priv(dev); | 3385 | struct sky2_port *sky2 = netdev_priv(dev); |
| 3354 | struct sky2_hw *hw = sky2->hw; | 3386 | unsigned int i; |
| 3355 | unsigned port = sky2->port; | ||
| 3356 | u16 ledctrl, ledover = 0; | ||
| 3357 | long ms; | ||
| 3358 | int interrupted; | ||
| 3359 | int onoff = 1; | ||
| 3360 | 3387 | ||
| 3361 | if (!data || data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ)) | 3388 | if (data == 0) |
| 3362 | ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT); | 3389 | data = UINT_MAX; |
| 3363 | else | ||
| 3364 | ms = data * 1000; | ||
| 3365 | |||
| 3366 | /* save initial values */ | ||
| 3367 | spin_lock_bh(&sky2->phy_lock); | ||
| 3368 | if (hw->chip_id == CHIP_ID_YUKON_XL) { | ||
| 3369 | u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); | ||
| 3370 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); | ||
| 3371 | ledctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); | ||
| 3372 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); | ||
| 3373 | } else { | ||
| 3374 | ledctrl = gm_phy_read(hw, port, PHY_MARV_LED_CTRL); | ||
| 3375 | ledover = gm_phy_read(hw, port, PHY_MARV_LED_OVER); | ||
| 3376 | } | ||
| 3377 | |||
| 3378 | interrupted = 0; | ||
| 3379 | while (!interrupted && ms > 0) { | ||
| 3380 | sky2_led(hw, port, onoff); | ||
| 3381 | onoff = !onoff; | ||
| 3382 | |||
| 3383 | spin_unlock_bh(&sky2->phy_lock); | ||
| 3384 | interrupted = msleep_interruptible(250); | ||
| 3385 | spin_lock_bh(&sky2->phy_lock); | ||
| 3386 | |||
| 3387 | ms -= 250; | ||
| 3388 | } | ||
| 3389 | 3390 | ||
| 3390 | /* resume regularly scheduled programming */ | 3391 | for (i = 0; i < data; i++) { |
| 3391 | if (hw->chip_id == CHIP_ID_YUKON_XL) { | 3392 | sky2_led(sky2, MO_LED_ON); |
| 3392 | u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); | 3393 | if (msleep_interruptible(500)) |
| 3393 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); | 3394 | break; |
| 3394 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ledctrl); | 3395 | sky2_led(sky2, MO_LED_OFF); |
| 3395 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); | 3396 | if (msleep_interruptible(500)) |
| 3396 | } else { | 3397 | break; |
| 3397 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); | ||
| 3398 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); | ||
| 3399 | } | 3398 | } |
| 3400 | spin_unlock_bh(&sky2->phy_lock); | 3399 | sky2_led(sky2, MO_LED_NORM); |
| 3401 | 3400 | ||
| 3402 | return 0; | 3401 | return 0; |
| 3403 | } | 3402 | } |
