X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fnet%2Fmv643xx_eth.c;h=411f4d809c477d99175ee0eaa10257938a08d407;hb=40ef1d8d48e364dce689342adfdc475aa53f4808;hp=9f2661355a4acf3973e55b15d0ba24ba9d112959;hpb=74293759002aa7db0179158c20676a034614577b;p=linux-2.6 diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 9f2661355a..411f4d809c 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -281,10 +281,16 @@ static void mv643xx_eth_tx_timeout_task(struct net_device *dev) { struct mv643xx_private *mp = netdev_priv(dev); - netif_device_detach(dev); + if (!netif_running(dev)) + return; + + netif_stop_queue(dev); + eth_port_reset(mp->port_num); eth_port_start(dev); - netif_device_attach(dev); + + if (mp->tx_ring_size - mp->tx_desc_count >= MAX_DESCS_PER_SKB) + netif_wake_queue(dev); } /** @@ -552,9 +558,9 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id, #else if (eth_int_cause & ETH_INT_CAUSE_RX) mv643xx_eth_receive_queue(dev, INT_MAX); +#endif if (eth_int_cause_ext & ETH_INT_CAUSE_TX) mv643xx_eth_free_completed_tx_descs(dev); -#endif /* * If no real interrupt occured, exit. @@ -1186,7 +1192,12 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) BUG_ON(netif_queue_stopped(dev)); BUG_ON(skb == NULL); - BUG_ON(mp->tx_ring_size - mp->tx_desc_count < MAX_DESCS_PER_SKB); + + if (mp->tx_ring_size - mp->tx_desc_count < MAX_DESCS_PER_SKB) { + printk(KERN_ERR "%s: transmit with queue full\n", dev->name); + netif_stop_queue(dev); + return 1; + } if (has_tiny_unaligned_frags(skb)) { if ((skb_linearize(skb, GFP_ATOMIC) != 0)) { @@ -1408,6 +1419,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev) mv643xx_eth_update_pscr(dev, &cmd); mv643xx_set_settings(dev, &cmd); + SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &pdev->dev); err = register_netdev(dev); if (err) goto out;