diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 88 |
1 files changed, 59 insertions, 29 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 9b16c2a899e0..16a99f1ed171 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -304,7 +304,8 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
304 | struct sky2_port *sky2 = netdev_priv(hw->dev[port]); | 304 | struct sky2_port *sky2 = netdev_priv(hw->dev[port]); |
305 | u16 ctrl, ct1000, adv, pg, ledctrl, ledover; | 305 | u16 ctrl, ct1000, adv, pg, ledctrl, ledover; |
306 | 306 | ||
307 | if (sky2->autoneg == AUTONEG_ENABLE && hw->chip_id != CHIP_ID_YUKON_XL) { | 307 | if (sky2->autoneg == AUTONEG_ENABLE && |
308 | (hw->chip_id != CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) { | ||
308 | u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); | 309 | u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); |
309 | 310 | ||
310 | ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | | 311 | ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | |
@@ -332,7 +333,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
332 | ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO); | 333 | ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO); |
333 | 334 | ||
334 | if (sky2->autoneg == AUTONEG_ENABLE && | 335 | if (sky2->autoneg == AUTONEG_ENABLE && |
335 | hw->chip_id == CHIP_ID_YUKON_XL) { | 336 | (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) { |
336 | ctrl &= ~PHY_M_PC_DSC_MSK; | 337 | ctrl &= ~PHY_M_PC_DSC_MSK; |
337 | ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; | 338 | ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; |
338 | } | 339 | } |
@@ -448,10 +449,11 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
448 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); | 449 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); |
449 | 450 | ||
450 | /* set LED Function Control register */ | 451 | /* set LED Function Control register */ |
451 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ | 452 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, |
452 | PHY_M_LEDC_INIT_CTRL(7) | /* 10 Mbps */ | 453 | (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ |
453 | PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */ | 454 | PHY_M_LEDC_INIT_CTRL(7) | /* 10 Mbps */ |
454 | PHY_M_LEDC_STA0_CTRL(7))); /* 1000 Mbps */ | 455 | PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */ |
456 | PHY_M_LEDC_STA0_CTRL(7))); /* 1000 Mbps */ | ||
455 | 457 | ||
456 | /* set Polarity Control register */ | 458 | /* set Polarity Control register */ |
457 | gm_phy_write(hw, port, PHY_MARV_PHY_STAT, | 459 | gm_phy_write(hw, port, PHY_MARV_PHY_STAT, |
@@ -465,6 +467,25 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
465 | /* restore page register */ | 467 | /* restore page register */ |
466 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); | 468 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); |
467 | break; | 469 | break; |
470 | case CHIP_ID_YUKON_EC_U: | ||
471 | pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); | ||
472 | |||
473 | /* select page 3 to access LED control register */ | ||
474 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); | ||
475 | |||
476 | /* set LED Function Control register */ | ||
477 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, | ||
478 | (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ | ||
479 | PHY_M_LEDC_INIT_CTRL(8) | /* 10 Mbps */ | ||
480 | PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */ | ||
481 | PHY_M_LEDC_STA0_CTRL(7)));/* 1000 Mbps */ | ||
482 | |||
483 | /* set Blink Rate in LED Timer Control Register */ | ||
484 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, | ||
485 | ledctrl | PHY_M_LED_BLINK_RT(BLINK_84MS)); | ||
486 | /* restore page register */ | ||
487 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); | ||
488 | break; | ||
468 | 489 | ||
469 | default: | 490 | default: |
470 | /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ | 491 | /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ |
@@ -473,19 +494,21 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
473 | ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); | 494 | ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); |
474 | } | 495 | } |
475 | 496 | ||
476 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev >= 2) { | 497 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == CHIP_REV_YU_EC_A1) { |
477 | /* apply fixes in PHY AFE */ | 498 | /* apply fixes in PHY AFE */ |
478 | gm_phy_write(hw, port, 22, 255); | 499 | pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
500 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255); | ||
501 | |||
479 | /* increase differential signal amplitude in 10BASE-T */ | 502 | /* increase differential signal amplitude in 10BASE-T */ |
480 | gm_phy_write(hw, port, 24, 0xaa99); | 503 | gm_phy_write(hw, port, 0x18, 0xaa99); |
481 | gm_phy_write(hw, port, 23, 0x2011); | 504 | gm_phy_write(hw, port, 0x17, 0x2011); |
482 | 505 | ||
483 | /* fix for IEEE A/B Symmetry failure in 1000BASE-T */ | 506 | /* fix for IEEE A/B Symmetry failure in 1000BASE-T */ |
484 | gm_phy_write(hw, port, 24, 0xa204); | 507 | gm_phy_write(hw, port, 0x18, 0xa204); |
485 | gm_phy_write(hw, port, 23, 0x2002); | 508 | gm_phy_write(hw, port, 0x17, 0x2002); |
486 | 509 | ||
487 | /* set page register to 0 */ | 510 | /* set page register to 0 */ |
488 | gm_phy_write(hw, port, 22, 0); | 511 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); |
489 | } else { | 512 | } else { |
490 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); | 513 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); |
491 | 514 | ||
@@ -559,6 +582,11 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
559 | 582 | ||
560 | if (sky2->duplex == DUPLEX_FULL) | 583 | if (sky2->duplex == DUPLEX_FULL) |
561 | reg |= GM_GPCR_DUP_FULL; | 584 | reg |= GM_GPCR_DUP_FULL; |
585 | |||
586 | /* turn off pause in 10/100mbps half duplex */ | ||
587 | else if (sky2->speed != SPEED_1000 && | ||
588 | hw->chip_id != CHIP_ID_YUKON_EC_U) | ||
589 | sky2->tx_pause = sky2->rx_pause = 0; | ||
562 | } else | 590 | } else |
563 | reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL; | 591 | reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL; |
564 | 592 | ||
@@ -1504,17 +1532,26 @@ static void sky2_link_up(struct sky2_port *sky2) | |||
1504 | sky2_write8(hw, SK_REG(port, LNK_LED_REG), | 1532 | sky2_write8(hw, SK_REG(port, LNK_LED_REG), |
1505 | LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); | 1533 | LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); |
1506 | 1534 | ||
1507 | if (hw->chip_id == CHIP_ID_YUKON_XL) { | 1535 | if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U) { |
1508 | u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); | 1536 | u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
1537 | u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */ | ||
1538 | |||
1539 | switch(sky2->speed) { | ||
1540 | case SPEED_10: | ||
1541 | led |= PHY_M_LEDC_INIT_CTRL(7); | ||
1542 | break; | ||
1543 | |||
1544 | case SPEED_100: | ||
1545 | led |= PHY_M_LEDC_STA1_CTRL(7); | ||
1546 | break; | ||
1547 | |||
1548 | case SPEED_1000: | ||
1549 | led |= PHY_M_LEDC_STA0_CTRL(7); | ||
1550 | break; | ||
1551 | } | ||
1509 | 1552 | ||
1510 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); | 1553 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); |
1511 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ | 1554 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, led); |
1512 | PHY_M_LEDC_INIT_CTRL(sky2->speed == | ||
1513 | SPEED_10 ? 7 : 0) | | ||
1514 | PHY_M_LEDC_STA1_CTRL(sky2->speed == | ||
1515 | SPEED_100 ? 7 : 0) | | ||
1516 | PHY_M_LEDC_STA0_CTRL(sky2->speed == | ||
1517 | SPEED_1000 ? 7 : 0)); | ||
1518 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); | 1555 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); |
1519 | } | 1556 | } |
1520 | 1557 | ||
@@ -1589,7 +1626,7 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) | |||
1589 | sky2->speed = sky2_phy_speed(hw, aux); | 1626 | sky2->speed = sky2_phy_speed(hw, aux); |
1590 | 1627 | ||
1591 | /* Pause bits are offset (9..8) */ | 1628 | /* Pause bits are offset (9..8) */ |
1592 | if (hw->chip_id == CHIP_ID_YUKON_XL) | 1629 | if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U) |
1593 | aux >>= 6; | 1630 | aux >>= 6; |
1594 | 1631 | ||
1595 | sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0; | 1632 | sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0; |
@@ -2226,13 +2263,6 @@ static int __devinit sky2_reset(struct sky2_hw *hw) | |||
2226 | return -EOPNOTSUPP; | 2263 | return -EOPNOTSUPP; |
2227 | } | 2264 | } |
2228 | 2265 | ||
2229 | /* This chip is new and not tested yet */ | ||
2230 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { | ||
2231 | pr_info(PFX "%s: is a version of Yukon 2 chipset that has not been tested yet.\n", | ||
2232 | pci_name(hw->pdev)); | ||
2233 | pr_info("Please report success/failure to maintainer <shemminger@osdl.org>\n"); | ||
2234 | } | ||
2235 | |||
2236 | /* disable ASF */ | 2266 | /* disable ASF */ |
2237 | if (hw->chip_id <= CHIP_ID_YUKON_EC) { | 2267 | if (hw->chip_id <= CHIP_ID_YUKON_EC) { |
2238 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); | 2268 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); |