diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/sky2.c | 140 | ||||
| -rw-r--r-- | drivers/net/sky2.h | 1 |
2 files changed, 57 insertions, 84 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 822dd0b13133..09b94af3e65b 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
| @@ -192,76 +192,52 @@ static u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg) | |||
| 192 | return v; | 192 | return v; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | ||
| 196 | { | ||
| 197 | u16 power_control; | ||
| 198 | int vaux; | ||
| 199 | |||
| 200 | pr_debug("sky2_set_power_state %d\n", state); | ||
| 201 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | ||
| 202 | |||
| 203 | power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_PMC); | ||
| 204 | vaux = (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL) && | ||
| 205 | (power_control & PCI_PM_CAP_PME_D3cold); | ||
| 206 | |||
| 207 | power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_CTRL); | ||
| 208 | 195 | ||
| 209 | power_control |= PCI_PM_CTRL_PME_STATUS; | 196 | static void sky2_power_on(struct sky2_hw *hw) |
| 210 | power_control &= ~(PCI_PM_CTRL_STATE_MASK); | 197 | { |
| 211 | 198 | /* switch power to VCC (WA for VAUX problem) */ | |
| 212 | switch (state) { | 199 | sky2_write8(hw, B0_POWER_CTRL, |
| 213 | case PCI_D0: | 200 | PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); |
| 214 | /* switch power to VCC (WA for VAUX problem) */ | ||
| 215 | sky2_write8(hw, B0_POWER_CTRL, | ||
| 216 | PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); | ||
| 217 | |||
| 218 | /* disable Core Clock Division, */ | ||
| 219 | sky2_write32(hw, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS); | ||
| 220 | |||
| 221 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | ||
| 222 | /* enable bits are inverted */ | ||
| 223 | sky2_write8(hw, B2_Y2_CLK_GATE, | ||
| 224 | Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS | | ||
| 225 | Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS | | ||
| 226 | Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS); | ||
| 227 | else | ||
| 228 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | ||
| 229 | 201 | ||
| 230 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { | 202 | /* disable Core Clock Division, */ |
| 231 | u32 reg1; | 203 | sky2_write32(hw, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS); |
| 232 | 204 | ||
| 233 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); | 205 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) |
| 234 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); | 206 | /* enable bits are inverted */ |
| 235 | reg1 &= P_ASPM_CONTROL_MSK; | 207 | sky2_write8(hw, B2_Y2_CLK_GATE, |
| 236 | sky2_pci_write32(hw, PCI_DEV_REG4, reg1); | 208 | Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS | |
| 237 | sky2_pci_write32(hw, PCI_DEV_REG5, 0); | 209 | Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS | |
| 238 | } | 210 | Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS); |
| 211 | else | ||
| 212 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | ||
| 239 | 213 | ||
| 240 | break; | 214 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { |
| 215 | u32 reg1; | ||
| 241 | 216 | ||
| 242 | case PCI_D3hot: | 217 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); |
| 243 | case PCI_D3cold: | 218 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); |
| 244 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | 219 | reg1 &= P_ASPM_CONTROL_MSK; |
| 245 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | 220 | sky2_pci_write32(hw, PCI_DEV_REG4, reg1); |
| 246 | else | 221 | sky2_pci_write32(hw, PCI_DEV_REG5, 0); |
| 247 | /* enable bits are inverted */ | ||
| 248 | sky2_write8(hw, B2_Y2_CLK_GATE, | ||
| 249 | Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS | | ||
| 250 | Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS | | ||
| 251 | Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS); | ||
| 252 | |||
| 253 | /* switch power to VAUX */ | ||
| 254 | if (vaux && state != PCI_D3cold) | ||
| 255 | sky2_write8(hw, B0_POWER_CTRL, | ||
| 256 | (PC_VAUX_ENA | PC_VCC_ENA | | ||
| 257 | PC_VAUX_ON | PC_VCC_OFF)); | ||
| 258 | break; | ||
| 259 | default: | ||
| 260 | printk(KERN_ERR PFX "Unknown power state %d\n", state); | ||
| 261 | } | 222 | } |
| 223 | } | ||
| 262 | 224 | ||
| 263 | sky2_pci_write16(hw, hw->pm_cap + PCI_PM_CTRL, power_control); | 225 | static void sky2_power_aux(struct sky2_hw *hw) |
| 264 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | 226 | { |
| 227 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | ||
| 228 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | ||
| 229 | else | ||
| 230 | /* enable bits are inverted */ | ||
| 231 | sky2_write8(hw, B2_Y2_CLK_GATE, | ||
| 232 | Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS | | ||
| 233 | Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS | | ||
| 234 | Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS); | ||
| 235 | |||
| 236 | /* switch power to VAUX */ | ||
| 237 | if (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL) | ||
| 238 | sky2_write8(hw, B0_POWER_CTRL, | ||
| 239 | (PC_VAUX_ENA | PC_VCC_ENA | | ||
| 240 | PC_VAUX_ON | PC_VCC_OFF)); | ||
| 265 | } | 241 | } |
| 266 | 242 | ||
| 267 | static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port) | 243 | static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port) |
| @@ -2480,7 +2456,7 @@ static int sky2_reset(struct sky2_hw *hw) | |||
| 2480 | ++hw->ports; | 2456 | ++hw->ports; |
| 2481 | } | 2457 | } |
| 2482 | 2458 | ||
| 2483 | sky2_set_power_state(hw, PCI_D0); | 2459 | sky2_power_on(hw); |
| 2484 | 2460 | ||
| 2485 | for (i = 0; i < hw->ports; i++) { | 2461 | for (i = 0; i < hw->ports; i++) { |
| 2486 | sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); | 2462 | sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); |
| @@ -3376,7 +3352,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
| 3376 | { | 3352 | { |
| 3377 | struct net_device *dev, *dev1 = NULL; | 3353 | struct net_device *dev, *dev1 = NULL; |
| 3378 | struct sky2_hw *hw; | 3354 | struct sky2_hw *hw; |
| 3379 | int err, pm_cap, using_dac = 0; | 3355 | int err, using_dac = 0; |
| 3380 | 3356 | ||
| 3381 | err = pci_enable_device(pdev); | 3357 | err = pci_enable_device(pdev); |
| 3382 | if (err) { | 3358 | if (err) { |
| @@ -3394,15 +3370,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
| 3394 | 3370 | ||
| 3395 | pci_set_master(pdev); | 3371 | pci_set_master(pdev); |
| 3396 | 3372 | ||
| 3397 | /* Find power-management capability. */ | ||
| 3398 | pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); | ||
| 3399 | if (pm_cap == 0) { | ||
| 3400 | printk(KERN_ERR PFX "Cannot find PowerManagement capability, " | ||
| 3401 | "aborting.\n"); | ||
| 3402 | err = -EIO; | ||
| 3403 | goto err_out_free_regions; | ||
| 3404 | } | ||
| 3405 | |||
| 3406 | if (sizeof(dma_addr_t) > sizeof(u32) && | 3373 | if (sizeof(dma_addr_t) > sizeof(u32) && |
| 3407 | !(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) { | 3374 | !(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) { |
| 3408 | using_dac = 1; | 3375 | using_dac = 1; |
| @@ -3438,7 +3405,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
| 3438 | pci_name(pdev)); | 3405 | pci_name(pdev)); |
| 3439 | goto err_out_free_hw; | 3406 | goto err_out_free_hw; |
| 3440 | } | 3407 | } |
| 3441 | hw->pm_cap = pm_cap; | ||
| 3442 | 3408 | ||
| 3443 | #ifdef __BIG_ENDIAN | 3409 | #ifdef __BIG_ENDIAN |
| 3444 | /* The sk98lin vendor driver uses hardware byte swapping but | 3410 | /* The sk98lin vendor driver uses hardware byte swapping but |
| @@ -3555,7 +3521,8 @@ static void __devexit sky2_remove(struct pci_dev *pdev) | |||
| 3555 | unregister_netdev(dev1); | 3521 | unregister_netdev(dev1); |
| 3556 | unregister_netdev(dev0); | 3522 | unregister_netdev(dev0); |
| 3557 | 3523 | ||
| 3558 | sky2_set_power_state(hw, PCI_D3hot); | 3524 | sky2_power_aux(hw); |
| 3525 | |||
| 3559 | sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); | 3526 | sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); |
| 3560 | sky2_write8(hw, B0_CTST, CS_RST_SET); | 3527 | sky2_write8(hw, B0_CTST, CS_RST_SET); |
| 3561 | sky2_read8(hw, B0_CTST); | 3528 | sky2_read8(hw, B0_CTST); |
| @@ -3581,10 +3548,6 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 3581 | { | 3548 | { |
| 3582 | struct sky2_hw *hw = pci_get_drvdata(pdev); | 3549 | struct sky2_hw *hw = pci_get_drvdata(pdev); |
| 3583 | int i; | 3550 | int i; |
| 3584 | pci_power_t pstate = pci_choose_state(pdev, state); | ||
| 3585 | |||
| 3586 | if (!(pstate == PCI_D3hot || pstate == PCI_D3cold)) | ||
| 3587 | return -EINVAL; | ||
| 3588 | 3551 | ||
| 3589 | del_timer_sync(&hw->idle_timer); | 3552 | del_timer_sync(&hw->idle_timer); |
| 3590 | netif_poll_disable(hw->dev[0]); | 3553 | netif_poll_disable(hw->dev[0]); |
| @@ -3599,8 +3562,10 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 3599 | } | 3562 | } |
| 3600 | 3563 | ||
| 3601 | sky2_write32(hw, B0_IMSK, 0); | 3564 | sky2_write32(hw, B0_IMSK, 0); |
| 3565 | sky2_power_aux(hw); | ||
| 3602 | pci_save_state(pdev); | 3566 | pci_save_state(pdev); |
| 3603 | sky2_set_power_state(hw, pstate); | 3567 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
| 3568 | |||
| 3604 | return 0; | 3569 | return 0; |
| 3605 | } | 3570 | } |
| 3606 | 3571 | ||
| @@ -3609,9 +3574,15 @@ static int sky2_resume(struct pci_dev *pdev) | |||
| 3609 | struct sky2_hw *hw = pci_get_drvdata(pdev); | 3574 | struct sky2_hw *hw = pci_get_drvdata(pdev); |
| 3610 | int i, err; | 3575 | int i, err; |
| 3611 | 3576 | ||
| 3612 | pci_restore_state(pdev); | 3577 | err = pci_set_power_state(pdev, PCI_D0); |
| 3578 | if (err) | ||
| 3579 | goto out; | ||
| 3580 | |||
| 3581 | err = pci_restore_state(pdev); | ||
| 3582 | if (err) | ||
| 3583 | goto out; | ||
| 3584 | |||
| 3613 | pci_enable_wake(pdev, PCI_D0, 0); | 3585 | pci_enable_wake(pdev, PCI_D0, 0); |
| 3614 | sky2_set_power_state(hw, PCI_D0); | ||
| 3615 | 3586 | ||
| 3616 | err = sky2_reset(hw); | 3587 | err = sky2_reset(hw); |
| 3617 | if (err) | 3588 | if (err) |
| @@ -3636,7 +3607,10 @@ static int sky2_resume(struct pci_dev *pdev) | |||
| 3636 | 3607 | ||
| 3637 | netif_poll_enable(hw->dev[0]); | 3608 | netif_poll_enable(hw->dev[0]); |
| 3638 | sky2_idle_start(hw); | 3609 | sky2_idle_start(hw); |
| 3610 | return 0; | ||
| 3639 | out: | 3611 | out: |
| 3612 | printk(KERN_ERR PFX "%s: resume failed (%d)\n", pci_name(pdev), err); | ||
| 3613 | pci_disable_device(pdev); | ||
| 3640 | return err; | 3614 | return err; |
| 3641 | } | 3615 | } |
| 3642 | #endif | 3616 | #endif |
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 6ed1d47dbbd3..1f56600aad86 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
| @@ -1887,7 +1887,6 @@ struct sky2_hw { | |||
| 1887 | struct pci_dev *pdev; | 1887 | struct pci_dev *pdev; |
| 1888 | struct net_device *dev[2]; | 1888 | struct net_device *dev[2]; |
| 1889 | 1889 | ||
| 1890 | int pm_cap; | ||
| 1891 | u8 chip_id; | 1890 | u8 chip_id; |
| 1892 | u8 chip_rev; | 1891 | u8 chip_rev; |
| 1893 | u8 pmd_type; | 1892 | u8 pmd_type; |
