diff options
Diffstat (limited to 'drivers/net/sky2.c')
| -rw-r--r-- | drivers/net/sky2.c | 241 |
1 files changed, 196 insertions, 45 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index c8a5ef2d75f4..711e4a8948e0 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
| @@ -51,7 +51,7 @@ | |||
| 51 | #include "sky2.h" | 51 | #include "sky2.h" |
| 52 | 52 | ||
| 53 | #define DRV_NAME "sky2" | 53 | #define DRV_NAME "sky2" |
| 54 | #define DRV_VERSION "1.21" | 54 | #define DRV_VERSION "1.22" |
| 55 | #define PFX DRV_NAME " " | 55 | #define PFX DRV_NAME " " |
| 56 | 56 | ||
| 57 | /* | 57 | /* |
| @@ -98,7 +98,7 @@ static int disable_msi = 0; | |||
| 98 | module_param(disable_msi, int, 0); | 98 | module_param(disable_msi, int, 0); |
| 99 | MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); | 99 | MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); |
| 100 | 100 | ||
| 101 | static const struct pci_device_id sky2_id_table[] = { | 101 | static DEFINE_PCI_DEVICE_TABLE(sky2_id_table) = { |
| 102 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */ | 102 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */ |
| 103 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */ | 103 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */ |
| 104 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, /* DGE-560T */ | 104 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, /* DGE-560T */ |
| @@ -137,6 +137,7 @@ static const struct pci_device_id sky2_id_table[] = { | |||
| 137 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436C) }, /* 88E8072 */ | 137 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436C) }, /* 88E8072 */ |
| 138 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436D) }, /* 88E8055 */ | 138 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436D) }, /* 88E8055 */ |
| 139 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4370) }, /* 88E8075 */ | 139 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4370) }, /* 88E8075 */ |
| 140 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4380) }, /* 88E8057 */ | ||
| 140 | { 0 } | 141 | { 0 } |
| 141 | }; | 142 | }; |
| 142 | 143 | ||
| @@ -147,17 +148,6 @@ static const unsigned txqaddr[] = { Q_XA1, Q_XA2 }; | |||
| 147 | static const unsigned rxqaddr[] = { Q_R1, Q_R2 }; | 148 | static const unsigned rxqaddr[] = { Q_R1, Q_R2 }; |
| 148 | static const u32 portirq_msk[] = { Y2_IS_PORT_1, Y2_IS_PORT_2 }; | 149 | static const u32 portirq_msk[] = { Y2_IS_PORT_1, Y2_IS_PORT_2 }; |
| 149 | 150 | ||
| 150 | /* This driver supports yukon2 chipset only */ | ||
| 151 | static const char *yukon2_name[] = { | ||
| 152 | "XL", /* 0xb3 */ | ||
| 153 | "EC Ultra", /* 0xb4 */ | ||
| 154 | "Extreme", /* 0xb5 */ | ||
| 155 | "EC", /* 0xb6 */ | ||
| 156 | "FE", /* 0xb7 */ | ||
| 157 | "FE+", /* 0xb8 */ | ||
| 158 | "Supreme", /* 0xb9 */ | ||
| 159 | }; | ||
| 160 | |||
| 161 | static void sky2_set_multicast(struct net_device *dev); | 151 | static void sky2_set_multicast(struct net_device *dev); |
| 162 | 152 | ||
| 163 | /* Access to PHY via serial interconnect */ | 153 | /* Access to PHY via serial interconnect */ |
| @@ -285,6 +275,86 @@ static void sky2_power_aux(struct sky2_hw *hw) | |||
| 285 | PC_VAUX_ON | PC_VCC_OFF)); | 275 | PC_VAUX_ON | PC_VCC_OFF)); |
| 286 | } | 276 | } |
| 287 | 277 | ||
| 278 | static void sky2_power_state(struct sky2_hw *hw, pci_power_t state) | ||
| 279 | { | ||
| 280 | u16 power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_CTRL); | ||
| 281 | int pex = pci_find_capability(hw->pdev, PCI_CAP_ID_EXP); | ||
| 282 | u32 reg; | ||
| 283 | |||
| 284 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | ||
| 285 | |||
| 286 | switch (state) { | ||
| 287 | case PCI_D0: | ||
| 288 | break; | ||
| 289 | |||
| 290 | case PCI_D1: | ||
| 291 | power_control |= 1; | ||
| 292 | break; | ||
| 293 | |||
| 294 | case PCI_D2: | ||
| 295 | power_control |= 2; | ||
| 296 | break; | ||
| 297 | |||
| 298 | case PCI_D3hot: | ||
| 299 | case PCI_D3cold: | ||
| 300 | power_control |= 3; | ||
| 301 | if (hw->flags & SKY2_HW_ADV_POWER_CTL) { | ||
| 302 | /* additional power saving measurements */ | ||
| 303 | reg = sky2_pci_read32(hw, PCI_DEV_REG4); | ||
| 304 | |||
| 305 | /* set gating core clock for LTSSM in L1 state */ | ||
| 306 | reg |= P_PEX_LTSSM_STAT(P_PEX_LTSSM_L1_STAT) | | ||
| 307 | /* auto clock gated scheme controlled by CLKREQ */ | ||
| 308 | P_ASPM_A1_MODE_SELECT | | ||
| 309 | /* enable Gate Root Core Clock */ | ||
| 310 | P_CLK_GATE_ROOT_COR_ENA; | ||
| 311 | |||
| 312 | if (pex && (hw->flags & SKY2_HW_CLK_POWER)) { | ||
| 313 | /* enable Clock Power Management (CLKREQ) */ | ||
| 314 | u16 ctrl = sky2_pci_read16(hw, pex + PCI_EXP_DEVCTL); | ||
| 315 | |||
| 316 | ctrl |= PCI_EXP_DEVCTL_AUX_PME; | ||
| 317 | sky2_pci_write16(hw, pex + PCI_EXP_DEVCTL, ctrl); | ||
| 318 | } else | ||
| 319 | /* force CLKREQ Enable in Our4 (A1b only) */ | ||
| 320 | reg |= P_ASPM_FORCE_CLKREQ_ENA; | ||
| 321 | |||
| 322 | /* set Mask Register for Release/Gate Clock */ | ||
| 323 | sky2_pci_write32(hw, PCI_DEV_REG5, | ||
| 324 | P_REL_PCIE_EXIT_L1_ST | P_GAT_PCIE_ENTER_L1_ST | | ||
| 325 | P_REL_PCIE_RX_EX_IDLE | P_GAT_PCIE_RX_EL_IDLE | | ||
| 326 | P_REL_GPHY_LINK_UP | P_GAT_GPHY_LINK_DOWN); | ||
| 327 | } else | ||
| 328 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_CLK_HALT); | ||
| 329 | |||
| 330 | /* put CPU into reset state */ | ||
| 331 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, HCU_CCSR_ASF_RESET); | ||
| 332 | if (hw->chip_id == CHIP_ID_YUKON_SUPR && hw->chip_rev == CHIP_REV_YU_SU_A0) | ||
| 333 | /* put CPU into halt state */ | ||
| 334 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, HCU_CCSR_ASF_HALTED); | ||
| 335 | |||
| 336 | if (pex && !(hw->flags & SKY2_HW_RAM_BUFFER)) { | ||
| 337 | reg = sky2_pci_read32(hw, PCI_DEV_REG1); | ||
| 338 | /* force to PCIe L1 */ | ||
| 339 | reg |= PCI_FORCE_PEX_L1; | ||
| 340 | sky2_pci_write32(hw, PCI_DEV_REG1, reg); | ||
| 341 | } | ||
| 342 | break; | ||
| 343 | |||
| 344 | default: | ||
| 345 | dev_warn(&hw->pdev->dev, PFX "Invalid power state (%d) ", | ||
| 346 | state); | ||
| 347 | return; | ||
| 348 | } | ||
| 349 | |||
| 350 | power_control |= PCI_PM_CTRL_PME_ENABLE; | ||
| 351 | /* Finally, set the new power state. */ | ||
| 352 | sky2_pci_write32(hw, hw->pm_cap + PCI_PM_CTRL, power_control); | ||
| 353 | |||
| 354 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | ||
| 355 | sky2_pci_read32(hw, B0_CTST); | ||
| 356 | } | ||
| 357 | |||
| 288 | static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port) | 358 | static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port) |
| 289 | { | 359 | { |
| 290 | u16 reg; | 360 | u16 reg; |
| @@ -579,8 +649,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
| 579 | ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); | 649 | ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); |
| 580 | } | 650 | } |
| 581 | 651 | ||
| 582 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && | 652 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_UL_2) { |
| 583 | hw->chip_rev == CHIP_REV_YU_EC_U_A1) { | ||
| 584 | /* apply fixes in PHY AFE */ | 653 | /* apply fixes in PHY AFE */ |
| 585 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255); | 654 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255); |
| 586 | 655 | ||
| @@ -588,9 +657,11 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
| 588 | gm_phy_write(hw, port, 0x18, 0xaa99); | 657 | gm_phy_write(hw, port, 0x18, 0xaa99); |
| 589 | gm_phy_write(hw, port, 0x17, 0x2011); | 658 | gm_phy_write(hw, port, 0x17, 0x2011); |
| 590 | 659 | ||
| 591 | /* fix for IEEE A/B Symmetry failure in 1000BASE-T */ | 660 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { |
| 592 | gm_phy_write(hw, port, 0x18, 0xa204); | 661 | /* fix for IEEE A/B Symmetry failure in 1000BASE-T */ |
| 593 | gm_phy_write(hw, port, 0x17, 0x2002); | 662 | gm_phy_write(hw, port, 0x18, 0xa204); |
| 663 | gm_phy_write(hw, port, 0x17, 0x2002); | ||
| 664 | } | ||
| 594 | 665 | ||
| 595 | /* set page register to 0 */ | 666 | /* set page register to 0 */ |
| 596 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0); | 667 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0); |
| @@ -599,7 +670,8 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
| 599 | /* apply workaround for integrated resistors calibration */ | 670 | /* apply workaround for integrated resistors calibration */ |
| 600 | gm_phy_write(hw, port, PHY_MARV_PAGE_ADDR, 17); | 671 | gm_phy_write(hw, port, PHY_MARV_PAGE_ADDR, 17); |
| 601 | gm_phy_write(hw, port, PHY_MARV_PAGE_DATA, 0x3f60); | 672 | gm_phy_write(hw, port, PHY_MARV_PAGE_DATA, 0x3f60); |
| 602 | } else if (hw->chip_id != CHIP_ID_YUKON_EX) { | 673 | } else if (hw->chip_id != CHIP_ID_YUKON_EX && |
| 674 | hw->chip_id < CHIP_ID_YUKON_SUPR) { | ||
| 603 | /* no effect on Yukon-XL */ | 675 | /* no effect on Yukon-XL */ |
| 604 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); | 676 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); |
| 605 | 677 | ||
| @@ -620,28 +692,71 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
| 620 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); | 692 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); |
| 621 | } | 693 | } |
| 622 | 694 | ||
| 623 | static void sky2_phy_power(struct sky2_hw *hw, unsigned port, int onoff) | 695 | static const u32 phy_power[] = { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD }; |
| 696 | static const u32 coma_mode[] = { PCI_Y2_PHY1_COMA, PCI_Y2_PHY2_COMA }; | ||
| 697 | |||
| 698 | static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port) | ||
| 624 | { | 699 | { |
| 625 | u32 reg1; | 700 | u32 reg1; |
| 626 | static const u32 phy_power[] = { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD }; | ||
| 627 | static const u32 coma_mode[] = { PCI_Y2_PHY1_COMA, PCI_Y2_PHY2_COMA }; | ||
| 628 | 701 | ||
| 629 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | 702 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
| 630 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); | 703 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); |
| 631 | /* Turn on/off phy power saving */ | 704 | reg1 &= ~phy_power[port]; |
| 632 | if (onoff) | ||
| 633 | reg1 &= ~phy_power[port]; | ||
| 634 | else | ||
| 635 | reg1 |= phy_power[port]; | ||
| 636 | 705 | ||
| 637 | if (onoff && hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | 706 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) |
| 638 | reg1 |= coma_mode[port]; | 707 | reg1 |= coma_mode[port]; |
| 639 | 708 | ||
| 640 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | 709 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); |
| 641 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | 710 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
| 642 | sky2_pci_read32(hw, PCI_DEV_REG1); | 711 | sky2_pci_read32(hw, PCI_DEV_REG1); |
| 712 | } | ||
| 713 | |||
| 714 | static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port) | ||
| 715 | { | ||
| 716 | u32 reg1; | ||
| 717 | u16 ctrl; | ||
| 718 | |||
| 719 | /* release GPHY Control reset */ | ||
| 720 | sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); | ||
| 721 | |||
| 722 | /* release GMAC reset */ | ||
| 723 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR); | ||
| 724 | |||
| 725 | if (hw->flags & SKY2_HW_NEWER_PHY) { | ||
| 726 | /* select page 2 to access MAC control register */ | ||
| 727 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2); | ||
| 643 | 728 | ||
| 644 | udelay(100); | 729 | ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); |
| 730 | /* allow GMII Power Down */ | ||
| 731 | ctrl &= ~PHY_M_MAC_GMIF_PUP; | ||
| 732 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); | ||
| 733 | |||
| 734 | /* set page register back to 0 */ | ||
| 735 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0); | ||
| 736 | } | ||
| 737 | |||
| 738 | /* setup General Purpose Control Register */ | ||
| 739 | gma_write16(hw, port, GM_GP_CTRL, | ||
| 740 | GM_GPCR_FL_PASS | GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS); | ||
| 741 | |||
| 742 | if (hw->chip_id != CHIP_ID_YUKON_EC) { | ||
| 743 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { | ||
| 744 | ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); | ||
| 745 | |||
| 746 | /* enable Power Down */ | ||
| 747 | ctrl |= PHY_M_PC_POW_D_ENA; | ||
| 748 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); | ||
| 749 | } | ||
| 750 | |||
| 751 | /* set IEEE compatible Power Down Mode (dev. #4.99) */ | ||
| 752 | gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_PDOWN); | ||
| 753 | } | ||
| 754 | |||
| 755 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | ||
| 756 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); | ||
| 757 | reg1 |= phy_power[port]; /* set PHY to PowerDown/COMA Mode */ | ||
| 758 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | ||
| 759 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | ||
| 645 | } | 760 | } |
| 646 | 761 | ||
| 647 | /* Force a renegotiation */ | 762 | /* Force a renegotiation */ |
| @@ -676,8 +791,11 @@ static void sky2_wol_init(struct sky2_port *sky2) | |||
| 676 | 791 | ||
| 677 | sky2->advertising &= ~(ADVERTISED_1000baseT_Half|ADVERTISED_1000baseT_Full); | 792 | sky2->advertising &= ~(ADVERTISED_1000baseT_Half|ADVERTISED_1000baseT_Full); |
| 678 | sky2->flow_mode = FC_NONE; | 793 | sky2->flow_mode = FC_NONE; |
| 679 | sky2_phy_power(hw, port, 1); | 794 | |
| 680 | sky2_phy_reinit(sky2); | 795 | spin_lock_bh(&sky2->phy_lock); |
| 796 | sky2_phy_power_up(hw, port); | ||
| 797 | sky2_phy_init(hw, port); | ||
| 798 | spin_unlock_bh(&sky2->phy_lock); | ||
| 681 | 799 | ||
| 682 | sky2->flow_mode = save_mode; | 800 | sky2->flow_mode = save_mode; |
| 683 | sky2->advertising = ctrl; | 801 | sky2->advertising = ctrl; |
| @@ -782,6 +900,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
| 782 | sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK); | 900 | sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK); |
| 783 | 901 | ||
| 784 | spin_lock_bh(&sky2->phy_lock); | 902 | spin_lock_bh(&sky2->phy_lock); |
| 903 | sky2_phy_power_up(hw, port); | ||
| 785 | sky2_phy_init(hw, port); | 904 | sky2_phy_init(hw, port); |
| 786 | spin_unlock_bh(&sky2->phy_lock); | 905 | spin_unlock_bh(&sky2->phy_lock); |
| 787 | 906 | ||
| @@ -1386,8 +1505,6 @@ static int sky2_up(struct net_device *dev) | |||
| 1386 | if (!sky2->rx_ring) | 1505 | if (!sky2->rx_ring) |
| 1387 | goto err_out; | 1506 | goto err_out; |
| 1388 | 1507 | ||
| 1389 | sky2_phy_power(hw, port, 1); | ||
| 1390 | |||
| 1391 | sky2_mac_init(hw, port); | 1508 | sky2_mac_init(hw, port); |
| 1392 | 1509 | ||
| 1393 | /* Register is number of 4K blocks on internal RAM buffer. */ | 1510 | /* Register is number of 4K blocks on internal RAM buffer. */ |
| @@ -1768,7 +1885,7 @@ static int sky2_down(struct net_device *dev) | |||
| 1768 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); | 1885 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); |
| 1769 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); | 1886 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); |
| 1770 | 1887 | ||
| 1771 | sky2_phy_power(hw, port, 0); | 1888 | sky2_phy_power_down(hw, port); |
| 1772 | 1889 | ||
| 1773 | netif_carrier_off(dev); | 1890 | netif_carrier_off(dev); |
| 1774 | 1891 | ||
| @@ -2694,6 +2811,7 @@ static u32 sky2_mhz(const struct sky2_hw *hw) | |||
| 2694 | case CHIP_ID_YUKON_EC_U: | 2811 | case CHIP_ID_YUKON_EC_U: |
| 2695 | case CHIP_ID_YUKON_EX: | 2812 | case CHIP_ID_YUKON_EX: |
| 2696 | case CHIP_ID_YUKON_SUPR: | 2813 | case CHIP_ID_YUKON_SUPR: |
| 2814 | case CHIP_ID_YUKON_UL_2: | ||
| 2697 | return 125; | 2815 | return 125; |
| 2698 | 2816 | ||
| 2699 | case CHIP_ID_YUKON_FE: | 2817 | case CHIP_ID_YUKON_FE: |
| @@ -2742,6 +2860,10 @@ static int __devinit sky2_init(struct sky2_hw *hw) | |||
| 2742 | hw->flags = SKY2_HW_GIGABIT | 2860 | hw->flags = SKY2_HW_GIGABIT |
| 2743 | | SKY2_HW_NEWER_PHY | 2861 | | SKY2_HW_NEWER_PHY |
| 2744 | | SKY2_HW_ADV_POWER_CTL; | 2862 | | SKY2_HW_ADV_POWER_CTL; |
| 2863 | |||
| 2864 | /* check for Rev. A1 dev 4200 */ | ||
| 2865 | if (sky2_read16(hw, Q_ADDR(Q_XA1, Q_WM)) == 0) | ||
| 2866 | hw->flags |= SKY2_HW_CLK_POWER; | ||
| 2745 | break; | 2867 | break; |
| 2746 | 2868 | ||
| 2747 | case CHIP_ID_YUKON_EX: | 2869 | case CHIP_ID_YUKON_EX: |
| @@ -2782,6 +2904,11 @@ static int __devinit sky2_init(struct sky2_hw *hw) | |||
| 2782 | | SKY2_HW_ADV_POWER_CTL; | 2904 | | SKY2_HW_ADV_POWER_CTL; |
| 2783 | break; | 2905 | break; |
| 2784 | 2906 | ||
| 2907 | case CHIP_ID_YUKON_UL_2: | ||
| 2908 | hw->flags = SKY2_HW_GIGABIT | ||
| 2909 | | SKY2_HW_ADV_POWER_CTL; | ||
| 2910 | break; | ||
| 2911 | |||
| 2785 | default: | 2912 | default: |
| 2786 | dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n", | 2913 | dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n", |
| 2787 | hw->chip_id); | 2914 | hw->chip_id); |
| @@ -2792,6 +2919,11 @@ static int __devinit sky2_init(struct sky2_hw *hw) | |||
| 2792 | if (hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P') | 2919 | if (hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P') |
| 2793 | hw->flags |= SKY2_HW_FIBRE_PHY; | 2920 | hw->flags |= SKY2_HW_FIBRE_PHY; |
| 2794 | 2921 | ||
| 2922 | hw->pm_cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PM); | ||
| 2923 | if (hw->pm_cap == 0) { | ||
| 2924 | dev_err(&hw->pdev->dev, "cannot find PowerManagement capability\n"); | ||
| 2925 | return -EIO; | ||
| 2926 | } | ||
| 2795 | 2927 | ||
| 2796 | hw->ports = 1; | 2928 | hw->ports = 1; |
| 2797 | t8 = sky2_read8(hw, B2_Y2_HW_RES); | 2929 | t8 = sky2_read8(hw, B2_Y2_HW_RES); |
| @@ -3379,7 +3511,7 @@ static void sky2_led(struct sky2_port *sky2, enum led_mode mode) | |||
| 3379 | 3511 | ||
| 3380 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); | 3512 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); |
| 3381 | } else | 3513 | } else |
| 3382 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, | 3514 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, |
| 3383 | PHY_M_LED_MO_DUP(mode) | | 3515 | PHY_M_LED_MO_DUP(mode) | |
| 3384 | PHY_M_LED_MO_10(mode) | | 3516 | PHY_M_LED_MO_10(mode) | |
| 3385 | PHY_M_LED_MO_100(mode) | | 3517 | PHY_M_LED_MO_100(mode) | |
| @@ -4132,12 +4264,34 @@ static int __devinit pci_wake_enabled(struct pci_dev *dev) | |||
| 4132 | return value & PCI_PM_CTRL_PME_ENABLE; | 4264 | return value & PCI_PM_CTRL_PME_ENABLE; |
| 4133 | } | 4265 | } |
| 4134 | 4266 | ||
| 4267 | /* This driver supports yukon2 chipset only */ | ||
| 4268 | static const char *sky2_name(u8 chipid, char *buf, int sz) | ||
| 4269 | { | ||
| 4270 | const char *name[] = { | ||
| 4271 | "XL", /* 0xb3 */ | ||
| 4272 | "EC Ultra", /* 0xb4 */ | ||
| 4273 | "Extreme", /* 0xb5 */ | ||
| 4274 | "EC", /* 0xb6 */ | ||
| 4275 | "FE", /* 0xb7 */ | ||
| 4276 | "FE+", /* 0xb8 */ | ||
| 4277 | "Supreme", /* 0xb9 */ | ||
| 4278 | "UL 2", /* 0xba */ | ||
| 4279 | }; | ||
| 4280 | |||
| 4281 | if (chipid >= CHIP_ID_YUKON_XL && chipid < CHIP_ID_YUKON_UL_2) | ||
| 4282 | strncpy(buf, name[chipid - CHIP_ID_YUKON_XL], sz); | ||
| 4283 | else | ||
| 4284 | snprintf(buf, sz, "(chip %#x)", chipid); | ||
| 4285 | return buf; | ||
| 4286 | } | ||
| 4287 | |||
| 4135 | static int __devinit sky2_probe(struct pci_dev *pdev, | 4288 | static int __devinit sky2_probe(struct pci_dev *pdev, |
| 4136 | const struct pci_device_id *ent) | 4289 | const struct pci_device_id *ent) |
| 4137 | { | 4290 | { |
| 4138 | struct net_device *dev; | 4291 | struct net_device *dev; |
| 4139 | struct sky2_hw *hw; | 4292 | struct sky2_hw *hw; |
| 4140 | int err, using_dac = 0, wol_default; | 4293 | int err, using_dac = 0, wol_default; |
| 4294 | char buf1[16]; | ||
| 4141 | 4295 | ||
| 4142 | err = pci_enable_device(pdev); | 4296 | err = pci_enable_device(pdev); |
| 4143 | if (err) { | 4297 | if (err) { |
| @@ -4208,10 +4362,10 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
| 4208 | if (err) | 4362 | if (err) |
| 4209 | goto err_out_iounmap; | 4363 | goto err_out_iounmap; |
| 4210 | 4364 | ||
| 4211 | dev_info(&pdev->dev, "v%s addr 0x%llx irq %d Yukon-%s (0x%x) rev %d\n", | 4365 | dev_info(&pdev->dev, "v%s addr 0x%llx irq %d Yukon-2 %s rev %d\n", |
| 4212 | DRV_VERSION, (unsigned long long)pci_resource_start(pdev, 0), | 4366 | DRV_VERSION, (unsigned long long)pci_resource_start(pdev, 0), |
| 4213 | pdev->irq, yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], | 4367 | pdev->irq, sky2_name(hw->chip_id, buf1, sizeof(buf1)), |
| 4214 | hw->chip_id, hw->chip_rev); | 4368 | hw->chip_rev); |
| 4215 | 4369 | ||
| 4216 | sky2_reset(hw); | 4370 | sky2_reset(hw); |
| 4217 | 4371 | ||
| @@ -4363,7 +4517,7 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 4363 | 4517 | ||
| 4364 | pci_save_state(pdev); | 4518 | pci_save_state(pdev); |
| 4365 | pci_enable_wake(pdev, pci_choose_state(pdev, state), wol); | 4519 | pci_enable_wake(pdev, pci_choose_state(pdev, state), wol); |
| 4366 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 4520 | sky2_power_state(hw, pci_choose_state(pdev, state)); |
| 4367 | 4521 | ||
| 4368 | return 0; | 4522 | return 0; |
| 4369 | } | 4523 | } |
| @@ -4376,9 +4530,7 @@ static int sky2_resume(struct pci_dev *pdev) | |||
| 4376 | if (!hw) | 4530 | if (!hw) |
| 4377 | return 0; | 4531 | return 0; |
| 4378 | 4532 | ||
| 4379 | err = pci_set_power_state(pdev, PCI_D0); | 4533 | sky2_power_state(hw, PCI_D0); |
| 4380 | if (err) | ||
| 4381 | goto out; | ||
| 4382 | 4534 | ||
| 4383 | err = pci_restore_state(pdev); | 4535 | err = pci_restore_state(pdev); |
| 4384 | if (err) | 4536 | if (err) |
| @@ -4448,8 +4600,7 @@ static void sky2_shutdown(struct pci_dev *pdev) | |||
| 4448 | pci_enable_wake(pdev, PCI_D3cold, wol); | 4600 | pci_enable_wake(pdev, PCI_D3cold, wol); |
| 4449 | 4601 | ||
| 4450 | pci_disable_device(pdev); | 4602 | pci_disable_device(pdev); |
| 4451 | pci_set_power_state(pdev, PCI_D3hot); | 4603 | sky2_power_state(hw, PCI_D3hot); |
| 4452 | |||
| 4453 | } | 4604 | } |
| 4454 | 4605 | ||
| 4455 | static struct pci_driver sky2_driver = { | 4606 | static struct pci_driver sky2_driver = { |
