e1000: fix loss of multicast packets
[safe/jmp/linux-2.6] / drivers / net / gianfar.c
index 8659833..65f5587 100644 (file)
@@ -289,9 +289,9 @@ static int gfar_of_init(struct net_device *dev)
                id = of_get_property(phy, "reg", NULL);
 
                of_node_put(phy);
-               of_node_put(mdio);
 
                fsl_pq_mdio_bus_name(bus_name, mdio);
+               of_node_put(mdio);
                snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), "%s:%02x",
                                bus_name, *id);
        }
@@ -549,7 +549,7 @@ static int gfar_remove(struct of_device *ofdev)
 static int gfar_suspend(struct of_device *ofdev, pm_message_t state)
 {
        struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
-       struct net_device *dev = priv->dev;
+       struct net_device *dev = priv->ndev;
        unsigned long flags;
        u32 tempval;
 
@@ -598,7 +598,7 @@ static int gfar_suspend(struct of_device *ofdev, pm_message_t state)
 static int gfar_resume(struct of_device *ofdev)
 {
        struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
-       struct net_device *dev = priv->dev;
+       struct net_device *dev = priv->ndev;
        unsigned long flags;
        u32 tempval;
        int magic_packet = priv->wol_en &&
@@ -1241,8 +1241,7 @@ static int gfar_enet_open(struct net_device *dev)
 
 static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb)
 {
-       struct txfcb *fcb = (struct txfcb *)skb_push (skb, GMAC_FCB_LEN);
-
+       struct txfcb *fcb = (struct txfcb *)skb_push(skb, GMAC_FCB_LEN);
        cacheable_memzero(fcb, GMAC_FCB_LEN);
 
        return fcb;
@@ -1311,6 +1310,22 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        base = priv->tx_bd_base;
 
+       /* make space for additional header when fcb is needed */
+       if (((skb->ip_summed == CHECKSUM_PARTIAL) ||
+                       (priv->vlgrp && vlan_tx_tag_present(skb))) &&
+                       (skb_headroom(skb) < GMAC_FCB_LEN)) {
+               struct sk_buff *skb_new;
+
+               skb_new = skb_realloc_headroom(skb, GMAC_FCB_LEN);
+               if (!skb_new) {
+                       dev->stats.tx_errors++;
+                       kfree_skb(skb);
+                       return NETDEV_TX_OK;
+               }
+               kfree_skb(skb);
+               skb = skb_new;
+       }
+
        /* total number of fragments in the SKB */
        nr_frags = skb_shinfo(skb)->nr_frags;
 
@@ -1422,7 +1437,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* Unlock priv */
        spin_unlock_irqrestore(&priv->txlock, flags);
 
-       return 0;
+       return NETDEV_TX_OK;
 }
 
 /* Stops the kernel queue, and halts the controller */