aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-02-06 13:45:39 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-07 18:49:59 -0500
commite3173832d7be8f62a181a1888a65f0a3dc58c2e0 (patch)
tree195129acd8ec02c265e7a8152f311cafaede1be5 /drivers
parentdde6d43d060bf0e0f38c66f76908e460db3bf0d8 (diff)
sky2: add Wake On Lan support
Adds basic magic packet wake on lan support to the sky2 driver. Note: initial WOL value is based on BIOS settings. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/sky2.c208
-rw-r--r--drivers/net/sky2.h28
2 files changed, 189 insertions, 47 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index bf1abf034d8a..f4c0bc19b005 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -567,6 +567,73 @@ static void sky2_phy_reinit(struct sky2_port *sky2)
567 spin_unlock_bh(&sky2->phy_lock); 567 spin_unlock_bh(&sky2->phy_lock);
568} 568}
569 569
570/* Put device in state to listen for Wake On Lan */
571static void sky2_wol_init(struct sky2_port *sky2)
572{
573 struct sky2_hw *hw = sky2->hw;
574 unsigned port = sky2->port;
575 enum flow_control save_mode;
576 u16 ctrl;
577 u32 reg1;
578
579 /* Bring hardware out of reset */
580 sky2_write16(hw, B0_CTST, CS_RST_CLR);
581 sky2_write16(hw, SK_REG(port, GMAC_LINK_CTRL), GMLC_RST_CLR);
582
583 sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
584 sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
585
586 /* Force to 10/100
587 * sky2_reset will re-enable on resume
588 */
589 save_mode = sky2->flow_mode;
590 ctrl = sky2->advertising;
591
592 sky2->advertising &= ~(ADVERTISED_1000baseT_Half|ADVERTISED_1000baseT_Full);
593 sky2->flow_mode = FC_NONE;
594 sky2_phy_power(hw, port, 1);
595 sky2_phy_reinit(sky2);
596
597 sky2->flow_mode = save_mode;
598 sky2->advertising = ctrl;
599
600 /* Set GMAC to no flow control and auto update for speed/duplex */
601 gma_write16(hw, port, GM_GP_CTRL,
602 GM_GPCR_FC_TX_DIS|GM_GPCR_TX_ENA|GM_GPCR_RX_ENA|
603 GM_GPCR_DUP_FULL|GM_GPCR_FC_RX_DIS|GM_GPCR_AU_FCT_DIS);
604
605 /* Set WOL address */
606 memcpy_toio(hw->regs + WOL_REGS(port, WOL_MAC_ADDR),
607 sky2->netdev->dev_addr, ETH_ALEN);
608
609 /* Turn on appropriate WOL control bits */
610 sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), WOL_CTL_CLEAR_RESULT);
611 ctrl = 0;
612 if (sky2->wol & WAKE_PHY)
613 ctrl |= WOL_CTL_ENA_PME_ON_LINK_CHG|WOL_CTL_ENA_LINK_CHG_UNIT;
614 else
615 ctrl |= WOL_CTL_DIS_PME_ON_LINK_CHG|WOL_CTL_DIS_LINK_CHG_UNIT;
616
617 if (sky2->wol & WAKE_MAGIC)
618 ctrl |= WOL_CTL_ENA_PME_ON_MAGIC_PKT|WOL_CTL_ENA_MAGIC_PKT_UNIT;
619 else
620 ctrl |= WOL_CTL_DIS_PME_ON_MAGIC_PKT|WOL_CTL_DIS_MAGIC_PKT_UNIT;;
621
622 ctrl |= WOL_CTL_DIS_PME_ON_PATTERN|WOL_CTL_DIS_PATTERN_UNIT;
623 sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), ctrl);
624
625 /* Turn on legacy PCI-Express PME mode */
626 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
627 reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
628 reg1 |= PCI_Y2_PME_LEGACY;
629 sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
630 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
631
632 /* block receiver */
633 sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
634
635}
636
570static void sky2_mac_init(struct sky2_hw *hw, unsigned port) 637static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
571{ 638{
572 struct sky2_port *sky2 = netdev_priv(hw->dev[port]); 639 struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
@@ -2404,11 +2471,9 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk)
2404} 2471}
2405 2472
2406 2473
2407static int sky2_reset(struct sky2_hw *hw) 2474static int __devinit sky2_init(struct sky2_hw *hw)
2408{ 2475{
2409 u16 status;
2410 u8 t8; 2476 u8 t8;
2411 int i;
2412 2477
2413 sky2_write8(hw, B0_CTST, CS_RST_CLR); 2478 sky2_write8(hw, B0_CTST, CS_RST_CLR);
2414 2479
@@ -2429,6 +2494,22 @@ static int sky2_reset(struct sky2_hw *hw)
2429 return -EOPNOTSUPP; 2494 return -EOPNOTSUPP;
2430 } 2495 }
2431 2496
2497 hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
2498 hw->ports = 1;
2499 t8 = sky2_read8(hw, B2_Y2_HW_RES);
2500 if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) {
2501 if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC))
2502 ++hw->ports;
2503 }
2504
2505 return 0;
2506}
2507
2508static void sky2_reset(struct sky2_hw *hw)
2509{
2510 u16 status;
2511 int i;
2512
2432 /* disable ASF */ 2513 /* disable ASF */
2433 if (hw->chip_id <= CHIP_ID_YUKON_EC) { 2514 if (hw->chip_id <= CHIP_ID_YUKON_EC) {
2434 sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); 2515 sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
@@ -2453,14 +2534,6 @@ static int sky2_reset(struct sky2_hw *hw)
2453 sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL); 2534 sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL);
2454 2535
2455 2536
2456 hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
2457 hw->ports = 1;
2458 t8 = sky2_read8(hw, B2_Y2_HW_RES);
2459 if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) {
2460 if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC))
2461 ++hw->ports;
2462 }
2463
2464 sky2_power_on(hw); 2537 sky2_power_on(hw);
2465 2538
2466 for (i = 0; i < hw->ports; i++) { 2539 for (i = 0; i < hw->ports; i++) {
@@ -2544,7 +2617,37 @@ static int sky2_reset(struct sky2_hw *hw)
2544 sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); 2617 sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
2545 sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START); 2618 sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
2546 sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START); 2619 sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
2620}
2621
2622static inline u8 sky2_wol_supported(const struct sky2_hw *hw)
2623{
2624 return sky2_is_copper(hw) ? (WAKE_PHY | WAKE_MAGIC) : 0;
2625}
2626
2627static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
2628{
2629 const struct sky2_port *sky2 = netdev_priv(dev);
2630
2631 wol->supported = sky2_wol_supported(sky2->hw);
2632 wol->wolopts = sky2->wol;
2633}
2634
2635static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
2636{
2637 struct sky2_port *sky2 = netdev_priv(dev);
2638 struct sky2_hw *hw = sky2->hw;
2547 2639
2640 if (wol->wolopts & ~sky2_wol_supported(sky2->hw))
2641 return -EOPNOTSUPP;
2642
2643 sky2->wol = wol->wolopts;
2644
2645 if (hw->chip_id == CHIP_ID_YUKON_EC_U)
2646 sky2_write32(hw, B0_CTST, sky2->wol
2647 ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF);
2648
2649 if (!netif_running(dev))
2650 sky2_wol_init(sky2);
2548 return 0; 2651 return 0;
2549} 2652}
2550 2653
@@ -3156,7 +3259,9 @@ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs,
3156static const struct ethtool_ops sky2_ethtool_ops = { 3259static const struct ethtool_ops sky2_ethtool_ops = {
3157 .get_settings = sky2_get_settings, 3260 .get_settings = sky2_get_settings,
3158 .set_settings = sky2_set_settings, 3261 .set_settings = sky2_set_settings,
3159 .get_drvinfo = sky2_get_drvinfo, 3262 .get_drvinfo = sky2_get_drvinfo,
3263 .get_wol = sky2_get_wol,
3264 .set_wol = sky2_set_wol,
3160 .get_msglevel = sky2_get_msglevel, 3265 .get_msglevel = sky2_get_msglevel,
3161 .set_msglevel = sky2_set_msglevel, 3266 .set_msglevel = sky2_set_msglevel,
3162 .nway_reset = sky2_nway_reset, 3267 .nway_reset = sky2_nway_reset,
@@ -3186,7 +3291,8 @@ static const struct ethtool_ops sky2_ethtool_ops = {
3186 3291
3187/* Initialize network device */ 3292/* Initialize network device */
3188static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, 3293static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
3189 unsigned port, int highmem) 3294 unsigned port,
3295 int highmem, int wol)
3190{ 3296{
3191 struct sky2_port *sky2; 3297 struct sky2_port *sky2;
3192 struct net_device *dev = alloc_etherdev(sizeof(*sky2)); 3298 struct net_device *dev = alloc_etherdev(sizeof(*sky2));
@@ -3234,6 +3340,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
3234 sky2->speed = -1; 3340 sky2->speed = -1;
3235 sky2->advertising = sky2_supported_modes(hw); 3341 sky2->advertising = sky2_supported_modes(hw);
3236 sky2->rx_csum = 1; 3342 sky2->rx_csum = 1;
3343 sky2->wol = wol;
3237 3344
3238 spin_lock_init(&sky2->phy_lock); 3345 spin_lock_init(&sky2->phy_lock);
3239 sky2->tx_pending = TX_DEF_PENDING; 3346 sky2->tx_pending = TX_DEF_PENDING;
@@ -3336,12 +3443,24 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw)
3336 return err; 3443 return err;
3337} 3444}
3338 3445
3446static int __devinit pci_wake_enabled(struct pci_dev *dev)
3447{
3448 int pm = pci_find_capability(dev, PCI_CAP_ID_PM);
3449 u16 value;
3450
3451 if (!pm)
3452 return 0;
3453 if (pci_read_config_word(dev, pm + PCI_PM_CTRL, &value))
3454 return 0;
3455 return value & PCI_PM_CTRL_PME_ENABLE;
3456}
3457
3339static int __devinit sky2_probe(struct pci_dev *pdev, 3458static int __devinit sky2_probe(struct pci_dev *pdev,
3340 const struct pci_device_id *ent) 3459 const struct pci_device_id *ent)
3341{ 3460{
3342 struct net_device *dev; 3461 struct net_device *dev;
3343 struct sky2_hw *hw; 3462 struct sky2_hw *hw;
3344 int err, using_dac = 0; 3463 int err, using_dac = 0, wol_default;
3345 3464
3346 err = pci_enable_device(pdev); 3465 err = pci_enable_device(pdev);
3347 if (err) { 3466 if (err) {
@@ -3378,6 +3497,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
3378 } 3497 }
3379 } 3498 }
3380 3499
3500 wol_default = pci_wake_enabled(pdev) ? WAKE_MAGIC : 0;
3501
3381 err = -ENOMEM; 3502 err = -ENOMEM;
3382 hw = kzalloc(sizeof(*hw), GFP_KERNEL); 3503 hw = kzalloc(sizeof(*hw), GFP_KERNEL);
3383 if (!hw) { 3504 if (!hw) {
@@ -3413,7 +3534,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
3413 if (!hw->st_le) 3534 if (!hw->st_le)
3414 goto err_out_iounmap; 3535 goto err_out_iounmap;
3415 3536
3416 err = sky2_reset(hw); 3537 err = sky2_init(hw);
3417 if (err) 3538 if (err)
3418 goto err_out_iounmap; 3539 goto err_out_iounmap;
3419 3540
@@ -3422,7 +3543,9 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
3422 pdev->irq, yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], 3543 pdev->irq, yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL],
3423 hw->chip_id, hw->chip_rev); 3544 hw->chip_id, hw->chip_rev);
3424 3545
3425 dev = sky2_init_netdev(hw, 0, using_dac); 3546 sky2_reset(hw);
3547
3548 dev = sky2_init_netdev(hw, 0, using_dac, wol_default);
3426 if (!dev) { 3549 if (!dev) {
3427 err = -ENOMEM; 3550 err = -ENOMEM;
3428 goto err_out_free_pci; 3551 goto err_out_free_pci;
@@ -3457,7 +3580,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
3457 if (hw->ports > 1) { 3580 if (hw->ports > 1) {
3458 struct net_device *dev1; 3581 struct net_device *dev1;
3459 3582
3460 dev1 = sky2_init_netdev(hw, 1, using_dac); 3583 dev1 = sky2_init_netdev(hw, 1, using_dac, wol_default);
3461 if (!dev1) { 3584 if (!dev1) {
3462 printk(KERN_WARNING PFX 3585 printk(KERN_WARNING PFX
3463 "allocation of second port failed\n"); 3586 "allocation of second port failed\n");
@@ -3544,23 +3667,29 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
3544static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) 3667static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
3545{ 3668{
3546 struct sky2_hw *hw = pci_get_drvdata(pdev); 3669 struct sky2_hw *hw = pci_get_drvdata(pdev);
3547 int i; 3670 int i, wol = 0;
3548 3671
3549 del_timer_sync(&hw->idle_timer); 3672 del_timer_sync(&hw->idle_timer);
3550 netif_poll_disable(hw->dev[0]); 3673 netif_poll_disable(hw->dev[0]);
3551 3674
3552 for (i = 0; i < hw->ports; i++) { 3675 for (i = 0; i < hw->ports; i++) {
3553 struct net_device *dev = hw->dev[i]; 3676 struct net_device *dev = hw->dev[i];
3677 struct sky2_port *sky2 = netdev_priv(dev);
3554 3678
3555 if (netif_running(dev)) { 3679 if (netif_running(dev))
3556 sky2_down(dev); 3680 sky2_down(dev);
3557 netif_device_detach(dev); 3681
3558 } 3682 if (sky2->wol)
3683 sky2_wol_init(sky2);
3684
3685 wol |= sky2->wol;
3559 } 3686 }
3560 3687
3561 sky2_write32(hw, B0_IMSK, 0); 3688 sky2_write32(hw, B0_IMSK, 0);
3562 sky2_power_aux(hw); 3689 sky2_power_aux(hw);
3690
3563 pci_save_state(pdev); 3691 pci_save_state(pdev);
3692 pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
3564 pci_set_power_state(pdev, pci_choose_state(pdev, state)); 3693 pci_set_power_state(pdev, pci_choose_state(pdev, state));
3565 3694
3566 return 0; 3695 return 0;
@@ -3580,18 +3709,13 @@ static int sky2_resume(struct pci_dev *pdev)
3580 goto out; 3709 goto out;
3581 3710
3582 pci_enable_wake(pdev, PCI_D0, 0); 3711 pci_enable_wake(pdev, PCI_D0, 0);
3583 3712 sky2_reset(hw);
3584 err = sky2_reset(hw);
3585 if (err)
3586 goto out;
3587 3713
3588 sky2_write32(hw, B0_IMSK, Y2_IS_BASE); 3714 sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
3589 3715
3590 for (i = 0; i < hw->ports; i++) { 3716 for (i = 0; i < hw->ports; i++) {
3591 struct net_device *dev = hw->dev[i]; 3717 struct net_device *dev = hw->dev[i];
3592 if (netif_running(dev)) { 3718 if (netif_running(dev)) {
3593 netif_device_attach(dev);
3594
3595 err = sky2_up(dev); 3719 err = sky2_up(dev);
3596 if (err) { 3720 if (err) {
3597 printk(KERN_ERR PFX "%s: could not up: %d\n", 3721 printk(KERN_ERR PFX "%s: could not up: %d\n",
@@ -3612,6 +3736,35 @@ out:
3612} 3736}
3613#endif 3737#endif
3614 3738
3739static void sky2_shutdown(struct pci_dev *pdev)
3740{
3741 struct sky2_hw *hw = pci_get_drvdata(pdev);
3742 int i, wol = 0;
3743
3744 del_timer_sync(&hw->idle_timer);
3745 netif_poll_disable(hw->dev[0]);
3746
3747 for (i = 0; i < hw->ports; i++) {
3748 struct net_device *dev = hw->dev[i];
3749 struct sky2_port *sky2 = netdev_priv(dev);
3750
3751 if (sky2->wol) {
3752 wol = 1;
3753 sky2_wol_init(sky2);
3754 }
3755 }
3756
3757 if (wol)
3758 sky2_power_aux(hw);
3759
3760 pci_enable_wake(pdev, PCI_D3hot, wol);
3761 pci_enable_wake(pdev, PCI_D3cold, wol);
3762
3763 pci_disable_device(pdev);
3764 pci_set_power_state(pdev, PCI_D3hot);
3765
3766}
3767
3615static struct pci_driver sky2_driver = { 3768static struct pci_driver sky2_driver = {
3616 .name = DRV_NAME, 3769 .name = DRV_NAME,
3617 .id_table = sky2_id_table, 3770 .id_table = sky2_id_table,
@@ -3621,6 +3774,7 @@ static struct pci_driver sky2_driver = {
3621 .suspend = sky2_suspend, 3774 .suspend = sky2_suspend,
3622 .resume = sky2_resume, 3775 .resume = sky2_resume,
3623#endif 3776#endif
3777 .shutdown = sky2_shutdown,
3624}; 3778};
3625 3779
3626static int __init sky2_init_module(void) 3780static int __init sky2_init_module(void)
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 1f56600aad86..a84584835ee1 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -32,6 +32,7 @@ enum pci_dev_reg_1 {
32 PCI_Y2_PHY1_COMA = 1<<28, /* Set PHY 1 to Coma Mode (YUKON-2) */ 32 PCI_Y2_PHY1_COMA = 1<<28, /* Set PHY 1 to Coma Mode (YUKON-2) */
33 PCI_Y2_PHY2_POWD = 1<<27, /* Set PHY 2 to Power Down (YUKON-2) */ 33 PCI_Y2_PHY2_POWD = 1<<27, /* Set PHY 2 to Power Down (YUKON-2) */
34 PCI_Y2_PHY1_POWD = 1<<26, /* Set PHY 1 to Power Down (YUKON-2) */ 34 PCI_Y2_PHY1_POWD = 1<<26, /* Set PHY 1 to Power Down (YUKON-2) */
35 PCI_Y2_PME_LEGACY= 1<<15, /* PCI Express legacy power management mode */
35}; 36};
36 37
37enum pci_dev_reg_2 { 38enum pci_dev_reg_2 {
@@ -837,33 +838,27 @@ enum {
837 GMAC_LINK_CTRL = 0x0f10,/* 16 bit Link Control Reg */ 838 GMAC_LINK_CTRL = 0x0f10,/* 16 bit Link Control Reg */
838 839
839/* Wake-up Frame Pattern Match Control Registers (YUKON only) */ 840/* Wake-up Frame Pattern Match Control Registers (YUKON only) */
840
841 WOL_REG_OFFS = 0x20,/* HW-Bug: Address is + 0x20 against spec. */
842
843 WOL_CTRL_STAT = 0x0f20,/* 16 bit WOL Control/Status Reg */ 841 WOL_CTRL_STAT = 0x0f20,/* 16 bit WOL Control/Status Reg */
844 WOL_MATCH_CTL = 0x0f22,/* 8 bit WOL Match Control Reg */ 842 WOL_MATCH_CTL = 0x0f22,/* 8 bit WOL Match Control Reg */
845 WOL_MATCH_RES = 0x0f23,/* 8 bit WOL Match Result Reg */ 843 WOL_MATCH_RES = 0x0f23,/* 8 bit WOL Match Result Reg */
846 WOL_MAC_ADDR = 0x0f24,/* 32 bit WOL MAC Address */ 844 WOL_MAC_ADDR = 0x0f24,/* 32 bit WOL MAC Address */
847 WOL_PATT_PME = 0x0f2a,/* 8 bit WOL PME Match Enable (Yukon-2) */
848 WOL_PATT_ASFM = 0x0f2b,/* 8 bit WOL ASF Match Enable (Yukon-2) */
849 WOL_PATT_RPTR = 0x0f2c,/* 8 bit WOL Pattern Read Pointer */ 845 WOL_PATT_RPTR = 0x0f2c,/* 8 bit WOL Pattern Read Pointer */
850 846
851/* WOL Pattern Length Registers (YUKON only) */ 847/* WOL Pattern Length Registers (YUKON only) */
852
853 WOL_PATT_LEN_LO = 0x0f30,/* 32 bit WOL Pattern Length 3..0 */ 848 WOL_PATT_LEN_LO = 0x0f30,/* 32 bit WOL Pattern Length 3..0 */
854 WOL_PATT_LEN_HI = 0x0f34,/* 24 bit WOL Pattern Length 6..4 */ 849 WOL_PATT_LEN_HI = 0x0f34,/* 24 bit WOL Pattern Length 6..4 */
855 850
856/* WOL Pattern Counter Registers (YUKON only) */ 851/* WOL Pattern Counter Registers (YUKON only) */
857
858
859 WOL_PATT_CNT_0 = 0x0f38,/* 32 bit WOL Pattern Counter 3..0 */ 852 WOL_PATT_CNT_0 = 0x0f38,/* 32 bit WOL Pattern Counter 3..0 */
860 WOL_PATT_CNT_4 = 0x0f3c,/* 24 bit WOL Pattern Counter 6..4 */ 853 WOL_PATT_CNT_4 = 0x0f3c,/* 24 bit WOL Pattern Counter 6..4 */
861}; 854};
855#define WOL_REGS(port, x) (x + (port)*0x80)
862 856
863enum { 857enum {
864 WOL_PATT_RAM_1 = 0x1000,/* WOL Pattern RAM Link 1 */ 858 WOL_PATT_RAM_1 = 0x1000,/* WOL Pattern RAM Link 1 */
865 WOL_PATT_RAM_2 = 0x1400,/* WOL Pattern RAM Link 2 */ 859 WOL_PATT_RAM_2 = 0x1400,/* WOL Pattern RAM Link 2 */
866}; 860};
861#define WOL_PATT_RAM_BASE(port) (WOL_PATT_RAM_1 + (port)*0x400)
867 862
868enum { 863enum {
869 BASE_GMAC_1 = 0x2800,/* GMAC 1 registers */ 864 BASE_GMAC_1 = 0x2800,/* GMAC 1 registers */
@@ -1715,14 +1710,17 @@ enum {
1715 GM_IS_RX_COMPL = 1<<0, /* Frame Reception Complete */ 1710 GM_IS_RX_COMPL = 1<<0, /* Frame Reception Complete */
1716 1711
1717#define GMAC_DEF_MSK GM_IS_TX_FF_UR 1712#define GMAC_DEF_MSK GM_IS_TX_FF_UR
1713};
1718 1714
1719/* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */ 1715/* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */
1720 /* Bits 15.. 2: reserved */ 1716enum { /* Bits 15.. 2: reserved */
1721 GMLC_RST_CLR = 1<<1, /* Clear GMAC Link Reset */ 1717 GMLC_RST_CLR = 1<<1, /* Clear GMAC Link Reset */
1722 GMLC_RST_SET = 1<<0, /* Set GMAC Link Reset */ 1718 GMLC_RST_SET = 1<<0, /* Set GMAC Link Reset */
1719};
1723 1720
1724 1721
1725/* WOL_CTRL_STAT 16 bit WOL Control/Status Reg */ 1722/* WOL_CTRL_STAT 16 bit WOL Control/Status Reg */
1723enum {
1726 WOL_CTL_LINK_CHG_OCC = 1<<15, 1724 WOL_CTL_LINK_CHG_OCC = 1<<15,
1727 WOL_CTL_MAGIC_PKT_OCC = 1<<14, 1725 WOL_CTL_MAGIC_PKT_OCC = 1<<14,
1728 WOL_CTL_PATTERN_OCC = 1<<13, 1726 WOL_CTL_PATTERN_OCC = 1<<13,
@@ -1741,17 +1739,6 @@ enum {
1741 WOL_CTL_DIS_PATTERN_UNIT = 1<<0, 1739 WOL_CTL_DIS_PATTERN_UNIT = 1<<0,
1742}; 1740};
1743 1741
1744#define WOL_CTL_DEFAULT \
1745 (WOL_CTL_DIS_PME_ON_LINK_CHG | \
1746 WOL_CTL_DIS_PME_ON_PATTERN | \
1747 WOL_CTL_DIS_PME_ON_MAGIC_PKT | \
1748 WOL_CTL_DIS_LINK_CHG_UNIT | \
1749 WOL_CTL_DIS_PATTERN_UNIT | \
1750 WOL_CTL_DIS_MAGIC_PKT_UNIT)
1751
1752/* WOL_MATCH_CTL 8 bit WOL Match Control Reg */
1753#define WOL_CTL_PATT_ENA(x) (1 << (x))
1754
1755 1742
1756/* Control flags */ 1743/* Control flags */
1757enum { 1744enum {
@@ -1875,6 +1862,7 @@ struct sky2_port {
1875 u8 autoneg; /* AUTONEG_ENABLE, AUTONEG_DISABLE */ 1862 u8 autoneg; /* AUTONEG_ENABLE, AUTONEG_DISABLE */
1876 u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */ 1863 u8 duplex; /* DUPLEX_HALF, DUPLEX_FULL */
1877 u8 rx_csum; 1864 u8 rx_csum;
1865 u8 wol;
1878 enum flow_control flow_mode; 1866 enum flow_control flow_mode;
1879 enum flow_control flow_status; 1867 enum flow_control flow_status;
1880 1868