|
Lines 308-314
static void sky2_phy_reset(struct sky2_h
Link Here
|
| 308 |
static void sky2_phy_init(struct sky2_hw *hw, unsigned port) |
308 |
static void sky2_phy_init(struct sky2_hw *hw, unsigned port) |
| 309 |
{ |
309 |
{ |
| 310 |
struct sky2_port *sky2 = netdev_priv(hw->dev[port]); |
310 |
struct sky2_port *sky2 = netdev_priv(hw->dev[port]); |
| 311 |
u16 ctrl, ct1000, adv, pg, ledctrl, ledover; |
311 |
u16 ctrl, ct1000, adv, pg, ledctrl, ledover, reg; |
| 312 |
|
312 |
|
| 313 |
if (sky2->autoneg == AUTONEG_ENABLE && |
313 |
if (sky2->autoneg == AUTONEG_ENABLE && |
| 314 |
!(hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) { |
314 |
!(hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) { |
|
Lines 389-394
static void sky2_phy_init(struct sky2_hw
Link Here
|
| 389 |
ctrl = 0; |
389 |
ctrl = 0; |
| 390 |
ct1000 = 0; |
390 |
ct1000 = 0; |
| 391 |
adv = PHY_AN_CSMA; |
391 |
adv = PHY_AN_CSMA; |
|
|
392 |
reg = 0; |
| 392 |
|
393 |
|
| 393 |
if (sky2->autoneg == AUTONEG_ENABLE) { |
394 |
if (sky2->autoneg == AUTONEG_ENABLE) { |
| 394 |
if (sky2_is_copper(hw)) { |
395 |
if (sky2_is_copper(hw)) { |
|
Lines 425-445
static void sky2_phy_init(struct sky2_hw
Link Here
|
| 425 |
/* forced speed/duplex settings */ |
426 |
/* forced speed/duplex settings */ |
| 426 |
ct1000 = PHY_M_1000C_MSE; |
427 |
ct1000 = PHY_M_1000C_MSE; |
| 427 |
|
428 |
|
| 428 |
if (sky2->duplex == DUPLEX_FULL) |
429 |
/* Disable auto update for duplex flow control and speed */ |
| 429 |
ctrl |= PHY_CT_DUP_MD; |
430 |
reg |= GM_GPCR_AU_ALL_DIS; |
| 430 |
|
431 |
|
| 431 |
switch (sky2->speed) { |
432 |
switch (sky2->speed) { |
| 432 |
case SPEED_1000: |
433 |
case SPEED_1000: |
| 433 |
ctrl |= PHY_CT_SP1000; |
434 |
ctrl |= PHY_CT_SP1000; |
|
|
435 |
reg |= GM_GPCR_SPEED_1000; |
| 434 |
break; |
436 |
break; |
| 435 |
case SPEED_100: |
437 |
case SPEED_100: |
| 436 |
ctrl |= PHY_CT_SP100; |
438 |
ctrl |= PHY_CT_SP100; |
|
|
439 |
reg |= GM_GPCR_SPEED_100; |
| 437 |
break; |
440 |
break; |
| 438 |
} |
441 |
} |
| 439 |
|
442 |
|
|
|
443 |
if (sky2->duplex == DUPLEX_FULL) { |
| 444 |
reg |= GM_GPCR_DUP_FULL; |
| 445 |
ctrl |= PHY_CT_DUP_MD; |
| 446 |
} else if (sky2->speed != SPEED_1000 && hw->chip_id != CHIP_ID_YUKON_EC_U) { |
| 447 |
/* Turn off flow control for 10/100mbps */ |
| 448 |
sky2->rx_pause = 0; |
| 449 |
sky2->tx_pause = 0; |
| 450 |
} |
| 451 |
|
| 452 |
if (!sky2->rx_pause) |
| 453 |
reg |= GM_GPCR_FC_RX_DIS; |
| 454 |
|
| 455 |
if (!sky2->tx_pause) |
| 456 |
reg |= GM_GPCR_FC_TX_DIS; |
| 457 |
|
| 458 |
/* Forward pause packets to GMAC? */ |
| 459 |
if (sky2->tx_pause || sky2->rx_pause) |
| 460 |
sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON); |
| 461 |
else |
| 462 |
sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); |
| 463 |
|
| 440 |
ctrl |= PHY_CT_RESET; |
464 |
ctrl |= PHY_CT_RESET; |
| 441 |
} |
465 |
} |
| 442 |
|
466 |
|
|
|
467 |
gma_write16(hw, port, GM_GP_CTRL, reg); |
| 468 |
|
| 443 |
if (hw->chip_id != CHIP_ID_YUKON_FE) |
469 |
if (hw->chip_id != CHIP_ID_YUKON_FE) |
| 444 |
gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000); |
470 |
gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000); |
| 445 |
|
471 |
|
|
Lines 543-548
static void sky2_phy_init(struct sky2_hw
Link Here
|
| 543 |
gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); |
569 |
gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); |
| 544 |
|
570 |
|
| 545 |
} |
571 |
} |
|
|
572 |
|
| 546 |
/* Enable phy interrupt on auto-negotiation complete (or link up) */ |
573 |
/* Enable phy interrupt on auto-negotiation complete (or link up) */ |
| 547 |
if (sky2->autoneg == AUTONEG_ENABLE) |
574 |
if (sky2->autoneg == AUTONEG_ENABLE) |
| 548 |
gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL); |
575 |
gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL); |
|
Lines 582-630
static void sky2_mac_init(struct sky2_hw
Link Here
|
| 582 |
gm_phy_read(hw, 1, PHY_MARV_INT_MASK) != 0); |
609 |
gm_phy_read(hw, 1, PHY_MARV_INT_MASK) != 0); |
| 583 |
} |
610 |
} |
| 584 |
|
611 |
|
| 585 |
if (sky2->autoneg == AUTONEG_DISABLE) { |
|
|
| 586 |
reg = gma_read16(hw, port, GM_GP_CTRL); |
| 587 |
reg |= GM_GPCR_AU_ALL_DIS; |
| 588 |
gma_write16(hw, port, GM_GP_CTRL, reg); |
| 589 |
gma_read16(hw, port, GM_GP_CTRL); |
| 590 |
|
| 591 |
switch (sky2->speed) { |
| 592 |
case SPEED_1000: |
| 593 |
reg &= ~GM_GPCR_SPEED_100; |
| 594 |
reg |= GM_GPCR_SPEED_1000; |
| 595 |
break; |
| 596 |
case SPEED_100: |
| 597 |
reg &= ~GM_GPCR_SPEED_1000; |
| 598 |
reg |= GM_GPCR_SPEED_100; |
| 599 |
break; |
| 600 |
case SPEED_10: |
| 601 |
reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100); |
| 602 |
break; |
| 603 |
} |
| 604 |
|
| 605 |
if (sky2->duplex == DUPLEX_FULL) |
| 606 |
reg |= GM_GPCR_DUP_FULL; |
| 607 |
|
| 608 |
/* turn off pause in 10/100mbps half duplex */ |
| 609 |
else if (sky2->speed != SPEED_1000 && |
| 610 |
hw->chip_id != CHIP_ID_YUKON_EC_U) |
| 611 |
sky2->tx_pause = sky2->rx_pause = 0; |
| 612 |
} else |
| 613 |
reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL; |
| 614 |
|
| 615 |
if (!sky2->tx_pause && !sky2->rx_pause) { |
| 616 |
sky2_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); |
| 617 |
reg |= |
| 618 |
GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; |
| 619 |
} else if (sky2->tx_pause && !sky2->rx_pause) { |
| 620 |
/* disable Rx flow-control */ |
| 621 |
reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; |
| 622 |
} |
| 623 |
|
| 624 |
gma_write16(hw, port, GM_GP_CTRL, reg); |
| 625 |
|
| 626 |
sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC)); |
612 |
sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC)); |
| 627 |
|
613 |
|
|
|
614 |
/* Enable Transmit FIFO Underrun */ |
| 615 |
sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK); |
| 616 |
|
| 628 |
spin_lock_bh(&sky2->phy_lock); |
617 |
spin_lock_bh(&sky2->phy_lock); |
| 629 |
sky2_phy_init(hw, port); |
618 |
sky2_phy_init(hw, port); |
| 630 |
spin_unlock_bh(&sky2->phy_lock); |
619 |
spin_unlock_bh(&sky2->phy_lock); |
|
Lines 1541-1580
static void sky2_link_up(struct sky2_por
Link Here
|
| 1541 |
unsigned port = sky2->port; |
1530 |
unsigned port = sky2->port; |
| 1542 |
u16 reg; |
1531 |
u16 reg; |
| 1543 |
|
1532 |
|
| 1544 |
/* Enable Transmit FIFO Underrun */ |
|
|
| 1545 |
sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK); |
| 1546 |
|
| 1547 |
reg = gma_read16(hw, port, GM_GP_CTRL); |
| 1548 |
if (sky2->autoneg == AUTONEG_DISABLE) { |
| 1549 |
reg |= GM_GPCR_AU_ALL_DIS; |
| 1550 |
|
| 1551 |
/* Is write/read necessary? Copied from sky2_mac_init */ |
| 1552 |
gma_write16(hw, port, GM_GP_CTRL, reg); |
| 1553 |
gma_read16(hw, port, GM_GP_CTRL); |
| 1554 |
|
| 1555 |
switch (sky2->speed) { |
| 1556 |
case SPEED_1000: |
| 1557 |
reg &= ~GM_GPCR_SPEED_100; |
| 1558 |
reg |= GM_GPCR_SPEED_1000; |
| 1559 |
break; |
| 1560 |
case SPEED_100: |
| 1561 |
reg &= ~GM_GPCR_SPEED_1000; |
| 1562 |
reg |= GM_GPCR_SPEED_100; |
| 1563 |
break; |
| 1564 |
case SPEED_10: |
| 1565 |
reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100); |
| 1566 |
break; |
| 1567 |
} |
| 1568 |
} else |
| 1569 |
reg &= ~GM_GPCR_AU_ALL_DIS; |
| 1570 |
|
| 1571 |
if (sky2->duplex == DUPLEX_FULL || sky2->autoneg == AUTONEG_ENABLE) |
| 1572 |
reg |= GM_GPCR_DUP_FULL; |
| 1573 |
|
| 1574 |
/* enable Rx/Tx */ |
1533 |
/* enable Rx/Tx */ |
|
|
1534 |
reg = gma_read16(hw, port, GM_GP_CTRL); |
| 1575 |
reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; |
1535 |
reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; |
| 1576 |
gma_write16(hw, port, GM_GP_CTRL, reg); |
1536 |
gma_write16(hw, port, GM_GP_CTRL, reg); |
| 1577 |
gma_read16(hw, port, GM_GP_CTRL); |
|
|
| 1578 |
|
1537 |
|
| 1579 |
gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); |
1538 |
gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); |
| 1580 |
|
1539 |
|
|
Lines 1628-1634
static void sky2_link_down(struct sky2_p
Link Here
|
| 1628 |
reg = gma_read16(hw, port, GM_GP_CTRL); |
1587 |
reg = gma_read16(hw, port, GM_GP_CTRL); |
| 1629 |
reg &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); |
1588 |
reg &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); |
| 1630 |
gma_write16(hw, port, GM_GP_CTRL, reg); |
1589 |
gma_write16(hw, port, GM_GP_CTRL, reg); |
| 1631 |
gma_read16(hw, port, GM_GP_CTRL); /* PCI post */ |
|
|
| 1632 |
|
1590 |
|
| 1633 |
if (sky2->rx_pause && !sky2->tx_pause) { |
1591 |
if (sky2->rx_pause && !sky2->tx_pause) { |
| 1634 |
/* restore Asymmetric Pause bit */ |
1592 |
/* restore Asymmetric Pause bit */ |
|
Lines 1645-1650
static void sky2_link_down(struct sky2_p
Link Here
|
| 1645 |
|
1603 |
|
| 1646 |
if (netif_msg_link(sky2)) |
1604 |
if (netif_msg_link(sky2)) |
| 1647 |
printk(KERN_INFO PFX "%s: Link is down.\n", sky2->netdev->name); |
1605 |
printk(KERN_INFO PFX "%s: Link is down.\n", sky2->netdev->name); |
|
|
1606 |
|
| 1648 |
sky2_phy_init(hw, port); |
1607 |
sky2_phy_init(hw, port); |
| 1649 |
} |
1608 |
} |
| 1650 |
|
1609 |
|
|
Lines 1685-1692
static int sky2_autoneg_done(struct sky2
Link Here
|
| 1685 |
sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0; |
1644 |
sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0; |
| 1686 |
sky2->tx_pause = (aux & PHY_M_PS_TX_P_EN) != 0; |
1645 |
sky2->tx_pause = (aux & PHY_M_PS_TX_P_EN) != 0; |
| 1687 |
|
1646 |
|
| 1688 |
if ((sky2->tx_pause || sky2->rx_pause) |
1647 |
if (sky2->duplex == DUPLEX_HALF && sky2->speed != SPEED_1000 |
| 1689 |
&& !(sky2->speed < SPEED_1000 && sky2->duplex == DUPLEX_HALF)) |
1648 |
&& hw->chip_id != CHIP_ID_YUKON_EC_U) |
|
|
1649 |
sky2->rx_pause = sky2->tx_pause = 0; |
| 1650 |
|
| 1651 |
if (sky2->rx_pause || sky2->tx_pause) |
| 1690 |
sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON); |
1652 |
sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON); |
| 1691 |
else |
1653 |
else |
| 1692 |
sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); |
1654 |
sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); |
|
Lines 1712-1718
static void sky2_phy_intr(struct sky2_hw
Link Here
|
| 1712 |
printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n", |
1674 |
printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n", |
| 1713 |
sky2->netdev->name, istatus, phystat); |
1675 |
sky2->netdev->name, istatus, phystat); |
| 1714 |
|
1676 |
|
| 1715 |
if (istatus & PHY_M_IS_AN_COMPL) { |
1677 |
if (sky2->autoneg == AUTONEG_ENABLE && (istatus & PHY_M_IS_AN_COMPL)) { |
| 1716 |
if (sky2_autoneg_done(sky2, phystat) == 0) |
1678 |
if (sky2_autoneg_done(sky2, phystat) == 0) |
| 1717 |
sky2_link_up(sky2); |
1679 |
sky2_link_up(sky2); |
| 1718 |
goto out; |
1680 |
goto out; |
|
Lines 2906-2912
static int sky2_set_pauseparam(struct ne
Link Here
|
| 2906 |
struct ethtool_pauseparam *ecmd) |
2868 |
struct ethtool_pauseparam *ecmd) |
| 2907 |
{ |
2869 |
{ |
| 2908 |
struct sky2_port *sky2 = netdev_priv(dev); |
2870 |
struct sky2_port *sky2 = netdev_priv(dev); |
| 2909 |
int err = 0; |
|
|
| 2910 |
|
2871 |
|
| 2911 |
sky2->autoneg = ecmd->autoneg; |
2872 |
sky2->autoneg = ecmd->autoneg; |
| 2912 |
sky2->tx_pause = ecmd->tx_pause != 0; |
2873 |
sky2->tx_pause = ecmd->tx_pause != 0; |
|
Lines 2914-2920
static int sky2_set_pauseparam(struct ne
Link Here
|
| 2914 |
|
2875 |
|
| 2915 |
sky2_phy_reinit(sky2); |
2876 |
sky2_phy_reinit(sky2); |
| 2916 |
|
2877 |
|
| 2917 |
return err; |
2878 |
return 0; |
| 2918 |
} |
2879 |
} |
| 2919 |
|
2880 |
|
| 2920 |
static int sky2_get_coalesce(struct net_device *dev, |
2881 |
static int sky2_get_coalesce(struct net_device *dev, |