aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ucc_geth.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-02-22 19:20:34 -0500
committerH. Peter Anvin <hpa@zytor.com>2010-02-22 19:20:34 -0500
commitd02e30c31c57683a66ed68a1bcff900ca78f6d56 (patch)
treec3ce99a00061bcc1199b50fa838147d876c56717 /drivers/net/ucc_geth.c
parent0fdc7a8022c3eaff6b5ee27ffb9e913e5e58d8e9 (diff)
parentaef55d4922e62a0d887e60d87319f3718aec6ced (diff)
Merge branch 'x86/irq' into x86/apic
Merge reason: Conflicts in arch/x86/kernel/apic/io_apic.c Resolved Conflicts: arch/x86/kernel/apic/io_apic.c Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'drivers/net/ucc_geth.c')
-rw-r--r--drivers/net/ucc_geth.c48
1 files changed, 27 insertions, 21 deletions
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index afaf088b72ea..eb8fe7e16c6c 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -1563,7 +1563,10 @@ static int ugeth_disable(struct ucc_geth_private *ugeth, enum comm_dir mode)
1563 1563
1564static void ugeth_quiesce(struct ucc_geth_private *ugeth) 1564static void ugeth_quiesce(struct ucc_geth_private *ugeth)
1565{ 1565{
1566 /* Wait for and prevent any further xmits. */ 1566 /* Prevent any further xmits, plus detach the device. */
1567 netif_device_detach(ugeth->ndev);
1568
1569 /* Wait for any current xmits to finish. */
1567 netif_tx_disable(ugeth->ndev); 1570 netif_tx_disable(ugeth->ndev);
1568 1571
1569 /* Disable the interrupt to avoid NAPI rescheduling. */ 1572 /* Disable the interrupt to avoid NAPI rescheduling. */
@@ -1577,7 +1580,7 @@ static void ugeth_activate(struct ucc_geth_private *ugeth)
1577{ 1580{
1578 napi_enable(&ugeth->napi); 1581 napi_enable(&ugeth->napi);
1579 enable_irq(ugeth->ug_info->uf_info.irq); 1582 enable_irq(ugeth->ug_info->uf_info.irq);
1580 netif_tx_wake_all_queues(ugeth->ndev); 1583 netif_device_attach(ugeth->ndev);
1581} 1584}
1582 1585
1583/* Called every time the controller might need to be made 1586/* Called every time the controller might need to be made
@@ -1648,25 +1651,28 @@ static void adjust_link(struct net_device *dev)
1648 ugeth->oldspeed = phydev->speed; 1651 ugeth->oldspeed = phydev->speed;
1649 } 1652 }
1650 1653
1651 /*
1652 * To change the MAC configuration we need to disable the
1653 * controller. To do so, we have to either grab ugeth->lock,
1654 * which is a bad idea since 'graceful stop' commands might
1655 * take quite a while, or we can quiesce driver's activity.
1656 */
1657 ugeth_quiesce(ugeth);
1658 ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
1659
1660 out_be32(&ug_regs->maccfg2, tempval);
1661 out_be32(&uf_regs->upsmr, upsmr);
1662
1663 ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
1664 ugeth_activate(ugeth);
1665
1666 if (!ugeth->oldlink) { 1654 if (!ugeth->oldlink) {
1667 new_state = 1; 1655 new_state = 1;
1668 ugeth->oldlink = 1; 1656 ugeth->oldlink = 1;
1669 } 1657 }
1658
1659 if (new_state) {
1660 /*
1661 * To change the MAC configuration we need to disable
1662 * the controller. To do so, we have to either grab
1663 * ugeth->lock, which is a bad idea since 'graceful
1664 * stop' commands might take quite a while, or we can
1665 * quiesce driver's activity.
1666 */
1667 ugeth_quiesce(ugeth);
1668 ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
1669
1670 out_be32(&ug_regs->maccfg2, tempval);
1671 out_be32(&uf_regs->upsmr, upsmr);
1672
1673 ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
1674 ugeth_activate(ugeth);
1675 }
1670 } else if (ugeth->oldlink) { 1676 } else if (ugeth->oldlink) {
1671 new_state = 1; 1677 new_state = 1;
1672 ugeth->oldlink = 0; 1678 ugeth->oldlink = 0;
@@ -3273,13 +3279,12 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
3273 /* Handle the transmitted buffer and release */ 3279 /* Handle the transmitted buffer and release */
3274 /* the BD to be used with the current frame */ 3280 /* the BD to be used with the current frame */
3275 3281
3276 if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) 3282 skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]];
3283 if (!skb)
3277 break; 3284 break;
3278 3285
3279 dev->stats.tx_packets++; 3286 dev->stats.tx_packets++;
3280 3287
3281 skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]];
3282
3283 if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN && 3288 if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN &&
3284 skb_recycle_check(skb, 3289 skb_recycle_check(skb,
3285 ugeth->ug_info->uf_info.max_rx_buf_length + 3290 ugeth->ug_info->uf_info.max_rx_buf_length +
@@ -3601,6 +3606,7 @@ static int ucc_geth_suspend(struct of_device *ofdev, pm_message_t state)
3601 if (!netif_running(ndev)) 3606 if (!netif_running(ndev))
3602 return 0; 3607 return 0;
3603 3608
3609 netif_device_detach(ndev);
3604 napi_disable(&ugeth->napi); 3610 napi_disable(&ugeth->napi);
3605 3611
3606 /* 3612 /*
@@ -3659,7 +3665,7 @@ static int ucc_geth_resume(struct of_device *ofdev)
3659 phy_start(ugeth->phydev); 3665 phy_start(ugeth->phydev);
3660 3666
3661 napi_enable(&ugeth->napi); 3667 napi_enable(&ugeth->napi);
3662 netif_start_queue(ndev); 3668 netif_device_attach(ndev);
3663 3669
3664 return 0; 3670 return 0;
3665} 3671}