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 | |
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>
-rw-r--r-- | drivers/net/sky2.c | 49 | ||||
-rw-r--r-- | drivers/net/sky2.h | 56 |
2 files changed, 89 insertions, 16 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 | ||
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index a84584835ee1..3b0189569d52 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
@@ -371,12 +371,9 @@ enum { | |||
371 | 371 | ||
372 | /* B2_CHIP_ID 8 bit Chip Identification Number */ | 372 | /* B2_CHIP_ID 8 bit Chip Identification Number */ |
373 | enum { | 373 | enum { |
374 | CHIP_ID_GENESIS = 0x0a, /* Chip ID for GENESIS */ | ||
375 | CHIP_ID_YUKON = 0xb0, /* Chip ID for YUKON */ | ||
376 | CHIP_ID_YUKON_LITE = 0xb1, /* Chip ID for YUKON-Lite (Rev. A1-A3) */ | ||
377 | CHIP_ID_YUKON_LP = 0xb2, /* Chip ID for YUKON-LP */ | ||
378 | CHIP_ID_YUKON_XL = 0xb3, /* Chip ID for YUKON-2 XL */ | 374 | CHIP_ID_YUKON_XL = 0xb3, /* Chip ID for YUKON-2 XL */ |
379 | CHIP_ID_YUKON_EC_U = 0xb4, /* Chip ID for YUKON-2 EC Ultra */ | 375 | CHIP_ID_YUKON_EC_U = 0xb4, /* Chip ID for YUKON-2 EC Ultra */ |
376 | CHIP_ID_YUKON_EX = 0xb5, /* Chip ID for YUKON-2 Extreme */ | ||
380 | CHIP_ID_YUKON_EC = 0xb6, /* Chip ID for YUKON-2 EC */ | 377 | CHIP_ID_YUKON_EC = 0xb6, /* Chip ID for YUKON-2 EC */ |
381 | CHIP_ID_YUKON_FE = 0xb7, /* Chip ID for YUKON-2 FE */ | 378 | CHIP_ID_YUKON_FE = 0xb7, /* Chip ID for YUKON-2 FE */ |
382 | 379 | ||
@@ -768,6 +765,24 @@ enum { | |||
768 | POLL_LIST_ADDR_HI= 0x0e2c,/* 32 bit Poll. List Start Addr (high) */ | 765 | POLL_LIST_ADDR_HI= 0x0e2c,/* 32 bit Poll. List Start Addr (high) */ |
769 | }; | 766 | }; |
770 | 767 | ||
768 | enum { | ||
769 | SMB_CFG = 0x0e40, /* 32 bit SMBus Config Register */ | ||
770 | SMB_CSR = 0x0e44, /* 32 bit SMBus Control/Status Register */ | ||
771 | }; | ||
772 | |||
773 | enum { | ||
774 | CPU_WDOG = 0x0e48, /* 32 bit Watchdog Register */ | ||
775 | CPU_CNTR = 0x0e4C, /* 32 bit Counter Register */ | ||
776 | CPU_TIM = 0x0e50,/* 32 bit Timer Compare Register */ | ||
777 | CPU_AHB_ADDR = 0x0e54, /* 32 bit CPU AHB Debug Register */ | ||
778 | CPU_AHB_WDATA = 0x0e58, /* 32 bit CPU AHB Debug Register */ | ||
779 | CPU_AHB_RDATA = 0x0e5C, /* 32 bit CPU AHB Debug Register */ | ||
780 | HCU_MAP_BASE = 0x0e60, /* 32 bit Reset Mapping Base */ | ||
781 | CPU_AHB_CTRL = 0x0e64, /* 32 bit CPU AHB Debug Register */ | ||
782 | HCU_CCSR = 0x0e68, /* 32 bit CPU Control and Status Register */ | ||
783 | HCU_HCSR = 0x0e6C, /* 32 bit Host Control and Status Register */ | ||
784 | }; | ||
785 | |||
771 | /* ASF Subsystem Registers (Yukon-2 only) */ | 786 | /* ASF Subsystem Registers (Yukon-2 only) */ |
772 | enum { | 787 | enum { |
773 | B28_Y2_SMB_CONFIG = 0x0e40,/* 32 bit ASF SMBus Config Register */ | 788 | B28_Y2_SMB_CONFIG = 0x0e40,/* 32 bit ASF SMBus Config Register */ |
@@ -1649,6 +1664,39 @@ enum { | |||
1649 | Y2_ASF_CLR_ASFI = 1<<1, /* Clear host IRQ */ | 1664 | Y2_ASF_CLR_ASFI = 1<<1, /* Clear host IRQ */ |
1650 | Y2_ASF_HOST_IRQ = 1<<0, /* Issue an IRQ to HOST system */ | 1665 | Y2_ASF_HOST_IRQ = 1<<0, /* Issue an IRQ to HOST system */ |
1651 | }; | 1666 | }; |
1667 | /* HCU_CCSR CPU Control and Status Register */ | ||
1668 | enum { | ||
1669 | HCU_CCSR_SMBALERT_MONITOR= 1<<27, /* SMBALERT pin monitor */ | ||
1670 | HCU_CCSR_CPU_SLEEP = 1<<26, /* CPU sleep status */ | ||
1671 | /* Clock Stretching Timeout */ | ||
1672 | HCU_CCSR_CS_TO = 1<<25, | ||
1673 | HCU_CCSR_WDOG = 1<<24, /* Watchdog Reset */ | ||
1674 | |||
1675 | HCU_CCSR_CLR_IRQ_HOST = 1<<17, /* Clear IRQ_HOST */ | ||
1676 | HCU_CCSR_SET_IRQ_HCU = 1<<16, /* Set IRQ_HCU */ | ||
1677 | |||
1678 | HCU_CCSR_AHB_RST = 1<<9, /* Reset AHB bridge */ | ||
1679 | HCU_CCSR_CPU_RST_MODE = 1<<8, /* CPU Reset Mode */ | ||
1680 | |||
1681 | HCU_CCSR_SET_SYNC_CPU = 1<<5, | ||
1682 | HCU_CCSR_CPU_CLK_DIVIDE_MSK = 3<<3,/* CPU Clock Divide */ | ||
1683 | HCU_CCSR_CPU_CLK_DIVIDE_BASE= 1<<3, | ||
1684 | HCU_CCSR_OS_PRSNT = 1<<2, /* ASF OS Present */ | ||
1685 | /* Microcontroller State */ | ||
1686 | HCU_CCSR_UC_STATE_MSK = 3, | ||
1687 | HCU_CCSR_UC_STATE_BASE = 1<<0, | ||
1688 | HCU_CCSR_ASF_RESET = 0, | ||
1689 | HCU_CCSR_ASF_HALTED = 1<<1, | ||
1690 | HCU_CCSR_ASF_RUNNING = 1<<0, | ||
1691 | }; | ||
1692 | |||
1693 | /* HCU_HCSR Host Control and Status Register */ | ||
1694 | enum { | ||
1695 | HCU_HCSR_SET_IRQ_CPU = 1<<16, /* Set IRQ_CPU */ | ||
1696 | |||
1697 | HCU_HCSR_CLR_IRQ_HCU = 1<<1, /* Clear IRQ_HCU */ | ||
1698 | HCU_HCSR_SET_IRQ_HOST = 1<<0, /* Set IRQ_HOST */ | ||
1699 | }; | ||
1652 | 1700 | ||
1653 | /* STAT_CTRL 32 bit Status BMU control register (Yukon-2 only) */ | 1701 | /* STAT_CTRL 32 bit Status BMU control register (Yukon-2 only) */ |
1654 | enum { | 1702 | enum { |