diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-06-13 20:28:05 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-06-13 20:28:05 -0400 |
commit | db9ca5803566078aafe63cf364ef98b5097e4194 (patch) | |
tree | ce330cdf21728f00801004e3900c79e4195cd516 /drivers/net/sky2.c | |
parent | bf717b11aec20965d48dea36dea3eea18a75d18c (diff) | |
parent | eb35cf60e462491249166182e3e755d3d5d91a28 (diff) |
Merge branch 'master' into upstream
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 46 |
1 files changed, 31 insertions, 15 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 959109609d85..97fe95666f3b 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -187,12 +187,11 @@ static u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg) | |||
187 | return v; | 187 | return v; |
188 | } | 188 | } |
189 | 189 | ||
190 | static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | 190 | static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) |
191 | { | 191 | { |
192 | u16 power_control; | 192 | u16 power_control; |
193 | u32 reg1; | 193 | u32 reg1; |
194 | int vaux; | 194 | int vaux; |
195 | int ret = 0; | ||
196 | 195 | ||
197 | pr_debug("sky2_set_power_state %d\n", state); | 196 | pr_debug("sky2_set_power_state %d\n", state); |
198 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | 197 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
@@ -275,12 +274,10 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
275 | break; | 274 | break; |
276 | default: | 275 | default: |
277 | printk(KERN_ERR PFX "Unknown power state %d\n", state); | 276 | printk(KERN_ERR PFX "Unknown power state %d\n", state); |
278 | ret = -1; | ||
279 | } | 277 | } |
280 | 278 | ||
281 | sky2_pci_write16(hw, hw->pm_cap + PCI_PM_CTRL, power_control); | 279 | sky2_pci_write16(hw, hw->pm_cap + PCI_PM_CTRL, power_control); |
282 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | 280 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
283 | return ret; | ||
284 | } | 281 | } |
285 | 282 | ||
286 | static void sky2_phy_reset(struct sky2_hw *hw, unsigned port) | 283 | static void sky2_phy_reset(struct sky2_hw *hw, unsigned port) |
@@ -2164,6 +2161,13 @@ static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port, | |||
2164 | /* If idle then force a fake soft NAPI poll once a second | 2161 | /* If idle then force a fake soft NAPI poll once a second |
2165 | * to work around cases where sharing an edge triggered interrupt. | 2162 | * to work around cases where sharing an edge triggered interrupt. |
2166 | */ | 2163 | */ |
2164 | static inline void sky2_idle_start(struct sky2_hw *hw) | ||
2165 | { | ||
2166 | if (idle_timeout > 0) | ||
2167 | mod_timer(&hw->idle_timer, | ||
2168 | jiffies + msecs_to_jiffies(idle_timeout)); | ||
2169 | } | ||
2170 | |||
2167 | static void sky2_idle(unsigned long arg) | 2171 | static void sky2_idle(unsigned long arg) |
2168 | { | 2172 | { |
2169 | struct sky2_hw *hw = (struct sky2_hw *) arg; | 2173 | struct sky2_hw *hw = (struct sky2_hw *) arg; |
@@ -2183,6 +2187,9 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
2183 | int work_done = 0; | 2187 | int work_done = 0; |
2184 | u32 status = sky2_read32(hw, B0_Y2_SP_EISR); | 2188 | u32 status = sky2_read32(hw, B0_Y2_SP_EISR); |
2185 | 2189 | ||
2190 | if (!~status) | ||
2191 | goto out; | ||
2192 | |||
2186 | if (status & Y2_IS_HW_ERR) | 2193 | if (status & Y2_IS_HW_ERR) |
2187 | sky2_hw_intr(hw); | 2194 | sky2_hw_intr(hw); |
2188 | 2195 | ||
@@ -2219,7 +2226,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
2219 | 2226 | ||
2220 | if (sky2_more_work(hw)) | 2227 | if (sky2_more_work(hw)) |
2221 | return 1; | 2228 | return 1; |
2222 | 2229 | out: | |
2223 | netif_rx_complete(dev0); | 2230 | netif_rx_complete(dev0); |
2224 | 2231 | ||
2225 | sky2_read32(hw, B0_Y2_SP_LISR); | 2232 | sky2_read32(hw, B0_Y2_SP_LISR); |
@@ -3350,9 +3357,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
3350 | sky2_write32(hw, B0_IMSK, Y2_IS_BASE); | 3357 | sky2_write32(hw, B0_IMSK, Y2_IS_BASE); |
3351 | 3358 | ||
3352 | setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw); | 3359 | setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw); |
3353 | if (idle_timeout > 0) | 3360 | sky2_idle_start(hw); |
3354 | mod_timer(&hw->idle_timer, | ||
3355 | jiffies + msecs_to_jiffies(idle_timeout)); | ||
3356 | 3361 | ||
3357 | pci_set_drvdata(pdev, hw); | 3362 | pci_set_drvdata(pdev, hw); |
3358 | 3363 | ||
@@ -3425,8 +3430,14 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3425 | { | 3430 | { |
3426 | struct sky2_hw *hw = pci_get_drvdata(pdev); | 3431 | struct sky2_hw *hw = pci_get_drvdata(pdev); |
3427 | int i; | 3432 | int i; |
3433 | pci_power_t pstate = pci_choose_state(pdev, state); | ||
3434 | |||
3435 | if (!(pstate == PCI_D3hot || pstate == PCI_D3cold)) | ||
3436 | return -EINVAL; | ||
3437 | |||
3438 | del_timer_sync(&hw->idle_timer); | ||
3428 | 3439 | ||
3429 | for (i = 0; i < 2; i++) { | 3440 | for (i = 0; i < hw->ports; i++) { |
3430 | struct net_device *dev = hw->dev[i]; | 3441 | struct net_device *dev = hw->dev[i]; |
3431 | 3442 | ||
3432 | if (dev) { | 3443 | if (dev) { |
@@ -3438,7 +3449,10 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3438 | } | 3449 | } |
3439 | } | 3450 | } |
3440 | 3451 | ||
3441 | return sky2_set_power_state(hw, pci_choose_state(pdev, state)); | 3452 | sky2_write32(hw, B0_IMSK, 0); |
3453 | pci_save_state(pdev); | ||
3454 | sky2_set_power_state(hw, pstate); | ||
3455 | return 0; | ||
3442 | } | 3456 | } |
3443 | 3457 | ||
3444 | static int sky2_resume(struct pci_dev *pdev) | 3458 | static int sky2_resume(struct pci_dev *pdev) |
@@ -3448,15 +3462,15 @@ static int sky2_resume(struct pci_dev *pdev) | |||
3448 | 3462 | ||
3449 | pci_restore_state(pdev); | 3463 | pci_restore_state(pdev); |
3450 | pci_enable_wake(pdev, PCI_D0, 0); | 3464 | pci_enable_wake(pdev, PCI_D0, 0); |
3451 | err = sky2_set_power_state(hw, PCI_D0); | 3465 | sky2_set_power_state(hw, PCI_D0); |
3452 | if (err) | ||
3453 | goto out; | ||
3454 | 3466 | ||
3455 | err = sky2_reset(hw); | 3467 | err = sky2_reset(hw); |
3456 | if (err) | 3468 | if (err) |
3457 | goto out; | 3469 | goto out; |
3458 | 3470 | ||
3459 | for (i = 0; i < 2; i++) { | 3471 | sky2_write32(hw, B0_IMSK, Y2_IS_BASE); |
3472 | |||
3473 | for (i = 0; i < hw->ports; i++) { | ||
3460 | struct net_device *dev = hw->dev[i]; | 3474 | struct net_device *dev = hw->dev[i]; |
3461 | if (dev && netif_running(dev)) { | 3475 | if (dev && netif_running(dev)) { |
3462 | netif_device_attach(dev); | 3476 | netif_device_attach(dev); |
@@ -3465,10 +3479,12 @@ static int sky2_resume(struct pci_dev *pdev) | |||
3465 | printk(KERN_ERR PFX "%s: could not up: %d\n", | 3479 | printk(KERN_ERR PFX "%s: could not up: %d\n", |
3466 | dev->name, err); | 3480 | dev->name, err); |
3467 | dev_close(dev); | 3481 | dev_close(dev); |
3468 | break; | 3482 | goto out; |
3469 | } | 3483 | } |
3470 | } | 3484 | } |
3471 | } | 3485 | } |
3486 | |||
3487 | sky2_idle_start(hw); | ||
3472 | out: | 3488 | out: |
3473 | return err; | 3489 | return err; |
3474 | } | 3490 | } |