aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-02-06 13:45:43 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-07 18:50:46 -0500
commit9374549428820be10f01e217cec1b34cb3e3de6d (patch)
treed35c1f19c1d2ee0780106aa91105746dfe46ae19
parent62335ab013d9eaef502bd402eb2eb72e8cff58f1 (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.c49
-rw-r--r--drivers/net/sky2.h56
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 };
140static const char *yukon2_name[] = { 140static 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 */
373enum { 373enum {
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
768enum {
769 SMB_CFG = 0x0e40, /* 32 bit SMBus Config Register */
770 SMB_CSR = 0x0e44, /* 32 bit SMBus Control/Status Register */
771};
772
773enum {
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) */
772enum { 787enum {
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 */
1668enum {
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 */
1694enum {
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) */
1654enum { 1702enum {