aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 959109609d85..fba1e4d4d83d 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
190static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) 190static 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
286static void sky2_phy_reset(struct sky2_hw *hw, unsigned port) 283static 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 */
2164static 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
2167static void sky2_idle(unsigned long arg) 2171static 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 2229out:
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);
@@ -2248,8 +2255,10 @@ static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs)
2248static void sky2_netpoll(struct net_device *dev) 2255static void sky2_netpoll(struct net_device *dev)
2249{ 2256{
2250 struct sky2_port *sky2 = netdev_priv(dev); 2257 struct sky2_port *sky2 = netdev_priv(dev);
2258 struct net_device *dev0 = sky2->hw->dev[0];
2251 2259
2252 sky2_intr(sky2->hw->pdev->irq, sky2->hw, NULL); 2260 if (netif_running(dev) && __netif_rx_schedule_prep(dev0))
2261 __netif_rx_schedule(dev0);
2253} 2262}
2254#endif 2263#endif
2255 2264
@@ -3350,9 +3359,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
3350 sky2_write32(hw, B0_IMSK, Y2_IS_BASE); 3359 sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
3351 3360
3352 setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw); 3361 setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw);
3353 if (idle_timeout > 0) 3362 sky2_idle_start(hw);
3354 mod_timer(&hw->idle_timer,
3355 jiffies + msecs_to_jiffies(idle_timeout));
3356 3363
3357 pci_set_drvdata(pdev, hw); 3364 pci_set_drvdata(pdev, hw);
3358 3365
@@ -3425,8 +3432,14 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
3425{ 3432{
3426 struct sky2_hw *hw = pci_get_drvdata(pdev); 3433 struct sky2_hw *hw = pci_get_drvdata(pdev);
3427 int i; 3434 int i;
3435 pci_power_t pstate = pci_choose_state(pdev, state);
3436
3437 if (!(pstate == PCI_D3hot || pstate == PCI_D3cold))
3438 return -EINVAL;
3439
3440 del_timer_sync(&hw->idle_timer);
3428 3441
3429 for (i = 0; i < 2; i++) { 3442 for (i = 0; i < hw->ports; i++) {
3430 struct net_device *dev = hw->dev[i]; 3443 struct net_device *dev = hw->dev[i];
3431 3444
3432 if (dev) { 3445 if (dev) {
@@ -3435,10 +3448,14 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
3435 3448
3436 sky2_down(dev); 3449 sky2_down(dev);
3437 netif_device_detach(dev); 3450 netif_device_detach(dev);
3451 netif_poll_disable(dev);
3438 } 3452 }
3439 } 3453 }
3440 3454
3441 return sky2_set_power_state(hw, pci_choose_state(pdev, state)); 3455 sky2_write32(hw, B0_IMSK, 0);
3456 pci_save_state(pdev);
3457 sky2_set_power_state(hw, pstate);
3458 return 0;
3442} 3459}
3443 3460
3444static int sky2_resume(struct pci_dev *pdev) 3461static int sky2_resume(struct pci_dev *pdev)
@@ -3448,27 +3465,31 @@ static int sky2_resume(struct pci_dev *pdev)
3448 3465
3449 pci_restore_state(pdev); 3466 pci_restore_state(pdev);
3450 pci_enable_wake(pdev, PCI_D0, 0); 3467 pci_enable_wake(pdev, PCI_D0, 0);
3451 err = sky2_set_power_state(hw, PCI_D0); 3468 sky2_set_power_state(hw, PCI_D0);
3452 if (err)
3453 goto out;
3454 3469
3455 err = sky2_reset(hw); 3470 err = sky2_reset(hw);
3456 if (err) 3471 if (err)
3457 goto out; 3472 goto out;
3458 3473
3459 for (i = 0; i < 2; i++) { 3474 sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
3475
3476 for (i = 0; i < hw->ports; i++) {
3460 struct net_device *dev = hw->dev[i]; 3477 struct net_device *dev = hw->dev[i];
3461 if (dev && netif_running(dev)) { 3478 if (dev && netif_running(dev)) {
3462 netif_device_attach(dev); 3479 netif_device_attach(dev);
3480 netif_poll_enable(dev);
3481
3463 err = sky2_up(dev); 3482 err = sky2_up(dev);
3464 if (err) { 3483 if (err) {
3465 printk(KERN_ERR PFX "%s: could not up: %d\n", 3484 printk(KERN_ERR PFX "%s: could not up: %d\n",
3466 dev->name, err); 3485 dev->name, err);
3467 dev_close(dev); 3486 dev_close(dev);
3468 break; 3487 goto out;
3469 } 3488 }
3470 } 3489 }
3471 } 3490 }
3491
3492 sky2_idle_start(hw);
3472out: 3493out:
3473 return err; 3494 return err;
3474} 3495}