aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c88
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);