diff options
author | Stephen Hemminger <shemminger@linux-foundation.org> | 2007-02-06 13:45:43 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-07 18:50:46 -0500 |
commit | 9374549428820be10f01e217cec1b34cb3e3de6d (patch) | |
tree | d35c1f19c1d2ee0780106aa91105746dfe46ae19 /drivers/net/sky2.c | |
parent | 62335ab013d9eaef502bd402eb2eb72e8cff58f1 (diff) |
sky2: Yukon Extreme support
This is basic support for the new Yukon Extreme
chip, extracted from the new vendor driver 10.0.4.3.
Since this is untested hardware, it has a big fat warning for now.
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 | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index c96362dae800..8cd38eb4b925 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -140,7 +140,7 @@ static const u32 portirq_msk[] = { Y2_IS_PORT_1, Y2_IS_PORT_2 }; | |||
140 | static const char *yukon2_name[] = { | 140 | static const char *yukon2_name[] = { |
141 | "XL", /* 0xb3 */ | 141 | "XL", /* 0xb3 */ |
142 | "EC Ultra", /* 0xb4 */ | 142 | "EC Ultra", /* 0xb4 */ |
143 | "UNKNOWN", /* 0xb5 */ | 143 | "Extreme", /* 0xb5 */ |
144 | "EC", /* 0xb6 */ | 144 | "EC", /* 0xb6 */ |
145 | "FE", /* 0xb7 */ | 145 | "FE", /* 0xb7 */ |
146 | }; | 146 | }; |
@@ -211,7 +211,7 @@ static void sky2_power_on(struct sky2_hw *hw) | |||
211 | else | 211 | else |
212 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | 212 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
213 | 213 | ||
214 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { | 214 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { |
215 | u32 reg1; | 215 | u32 reg1; |
216 | 216 | ||
217 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); | 217 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); |
@@ -289,8 +289,10 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
289 | struct sky2_port *sky2 = netdev_priv(hw->dev[port]); | 289 | struct sky2_port *sky2 = netdev_priv(hw->dev[port]); |
290 | u16 ctrl, ct1000, adv, pg, ledctrl, ledover, reg; | 290 | u16 ctrl, ct1000, adv, pg, ledctrl, ledover, reg; |
291 | 291 | ||
292 | if (sky2->autoneg == AUTONEG_ENABLE && | 292 | if (sky2->autoneg == AUTONEG_ENABLE |
293 | !(hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) { | 293 | && !(hw->chip_id == CHIP_ID_YUKON_XL |
294 | || hw->chip_id == CHIP_ID_YUKON_EC_U | ||
295 | || hw->chip_id == CHIP_ID_YUKON_EX)) { | ||
294 | u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); | 296 | u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); |
295 | 297 | ||
296 | ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | | 298 | ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | |
@@ -317,8 +319,10 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
317 | /* enable automatic crossover */ | 319 | /* enable automatic crossover */ |
318 | ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO); | 320 | ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO); |
319 | 321 | ||
320 | if (sky2->autoneg == AUTONEG_ENABLE && | 322 | if (sky2->autoneg == AUTONEG_ENABLE |
321 | (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) { | 323 | && (hw->chip_id == CHIP_ID_YUKON_XL |
324 | || hw->chip_id == CHIP_ID_YUKON_EC_U | ||
325 | || hw->chip_id == CHIP_ID_YUKON_EX)) { | ||
322 | ctrl &= ~PHY_M_PC_DSC_MSK; | 326 | ctrl &= ~PHY_M_PC_DSC_MSK; |
323 | ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; | 327 | ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; |
324 | } | 328 | } |
@@ -473,7 +477,9 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
473 | /* restore page register */ | 477 | /* restore page register */ |
474 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); | 478 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); |
475 | break; | 479 | break; |
480 | |||
476 | case CHIP_ID_YUKON_EC_U: | 481 | case CHIP_ID_YUKON_EC_U: |
482 | case CHIP_ID_YUKON_EX: | ||
477 | pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); | 483 | pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
478 | 484 | ||
479 | /* select page 3 to access LED control register */ | 485 | /* select page 3 to access LED control register */ |
@@ -515,7 +521,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
515 | 521 | ||
516 | /* set page register to 0 */ | 522 | /* set page register to 0 */ |
517 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); | 523 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); |
518 | } else { | 524 | } else if (hw->chip_id != CHIP_ID_YUKON_EX) { |
519 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); | 525 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); |
520 | 526 | ||
521 | if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { | 527 | if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { |
@@ -727,7 +733,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
727 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); | 733 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); |
728 | sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); | 734 | sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); |
729 | 735 | ||
730 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { | 736 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { |
731 | sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8); | 737 | sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8); |
732 | sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8); | 738 | sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8); |
733 | if (hw->dev[port]->mtu > ETH_DATA_LEN) { | 739 | if (hw->dev[port]->mtu > ETH_DATA_LEN) { |
@@ -1687,7 +1693,9 @@ static void sky2_link_up(struct sky2_port *sky2) | |||
1687 | sky2_write8(hw, SK_REG(port, LNK_LED_REG), | 1693 | sky2_write8(hw, SK_REG(port, LNK_LED_REG), |
1688 | LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); | 1694 | LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); |
1689 | 1695 | ||
1690 | if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U) { | 1696 | if (hw->chip_id == CHIP_ID_YUKON_XL |
1697 | || hw->chip_id == CHIP_ID_YUKON_EC_U | ||
1698 | || hw->chip_id == CHIP_ID_YUKON_EX) { | ||
1691 | u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); | 1699 | u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
1692 | u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */ | 1700 | u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */ |
1693 | 1701 | ||
@@ -1780,14 +1788,16 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) | |||
1780 | sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF; | 1788 | sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF; |
1781 | 1789 | ||
1782 | /* Pause bits are offset (9..8) */ | 1790 | /* Pause bits are offset (9..8) */ |
1783 | if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U) | 1791 | if (hw->chip_id == CHIP_ID_YUKON_XL |
1792 | || hw->chip_id == CHIP_ID_YUKON_EC_U | ||
1793 | || hw->chip_id == CHIP_ID_YUKON_EX) | ||
1784 | aux >>= 6; | 1794 | aux >>= 6; |
1785 | 1795 | ||
1786 | sky2->flow_status = sky2_flow(aux & PHY_M_PS_RX_P_EN, | 1796 | sky2->flow_status = sky2_flow(aux & PHY_M_PS_RX_P_EN, |
1787 | aux & PHY_M_PS_TX_P_EN); | 1797 | aux & PHY_M_PS_TX_P_EN); |
1788 | 1798 | ||
1789 | if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000 | 1799 | if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000 |
1790 | && hw->chip_id != CHIP_ID_YUKON_EC_U) | 1800 | && !(hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX)) |
1791 | sky2->flow_status = FC_NONE; | 1801 | sky2->flow_status = FC_NONE; |
1792 | 1802 | ||
1793 | if (aux & PHY_M_PS_RX_P_EN) | 1803 | if (aux & PHY_M_PS_RX_P_EN) |
@@ -2442,6 +2452,7 @@ static inline u32 sky2_mhz(const struct sky2_hw *hw) | |||
2442 | switch (hw->chip_id) { | 2452 | switch (hw->chip_id) { |
2443 | case CHIP_ID_YUKON_EC: | 2453 | case CHIP_ID_YUKON_EC: |
2444 | case CHIP_ID_YUKON_EC_U: | 2454 | case CHIP_ID_YUKON_EC_U: |
2455 | case CHIP_ID_YUKON_EX: | ||
2445 | return 125; /* 125 Mhz */ | 2456 | return 125; /* 125 Mhz */ |
2446 | case CHIP_ID_YUKON_FE: | 2457 | case CHIP_ID_YUKON_FE: |
2447 | return 100; /* 100 Mhz */ | 2458 | return 100; /* 100 Mhz */ |
@@ -2474,6 +2485,14 @@ static int __devinit sky2_init(struct sky2_hw *hw) | |||
2474 | return -EOPNOTSUPP; | 2485 | return -EOPNOTSUPP; |
2475 | } | 2486 | } |
2476 | 2487 | ||
2488 | if (hw->chip_id == CHIP_ID_YUKON_EX) | ||
2489 | dev_warn(&hw->pdev->dev, "this driver not yet tested on this chip type\n" | ||
2490 | "Please report success or failure to <netdev@vger.kernel.org>\n"); | ||
2491 | |||
2492 | /* Make sure and enable all clocks */ | ||
2493 | if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U) | ||
2494 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); | ||
2495 | |||
2477 | hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; | 2496 | hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; |
2478 | 2497 | ||
2479 | /* This rev is really old, and requires untested workarounds */ | 2498 | /* This rev is really old, and requires untested workarounds */ |
@@ -2502,7 +2521,13 @@ static void sky2_reset(struct sky2_hw *hw) | |||
2502 | 2521 | ||
2503 | /* disable ASF */ | 2522 | /* disable ASF */ |
2504 | if (hw->chip_id <= CHIP_ID_YUKON_EC) { | 2523 | if (hw->chip_id <= CHIP_ID_YUKON_EC) { |
2505 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); | 2524 | if (hw->chip_id == CHIP_ID_YUKON_EX) { |
2525 | status = sky2_read16(hw, HCU_CCSR); | ||
2526 | status &= ~(HCU_CCSR_AHB_RST | HCU_CCSR_CPU_RST_MODE | | ||
2527 | HCU_CCSR_UC_STATE_MSK); | ||
2528 | sky2_write16(hw, HCU_CCSR, status); | ||
2529 | } else | ||
2530 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); | ||
2506 | sky2_write16(hw, B0_CTST, Y2_ASF_DISABLE); | 2531 | sky2_write16(hw, B0_CTST, Y2_ASF_DISABLE); |
2507 | } | 2532 | } |
2508 | 2533 | ||