@@ -242,11 +242,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
unsigned short status;
unsigned long flags;
- if (!fep->link) {
- /* Link is down or autonegotiation is in progress. */
- return NETDEV_TX_BUSY;
- }
-
spin_lock_irqsave(&fep->hw_lock, flags);
/* Fill in a Tx ring entry */
bdp = fep->cur_tx;
@@ -470,6 +465,9 @@ fec_stop(struct net_device *ndev)
udelay(10);
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
+
+ netif_stop_queue(ndev);
+ fep->link = 0;
}
@@ -787,6 +785,7 @@ static void fec_enet_adjust_link(struct net_device *ndev)
if (phy_dev->link) {
if (fep->full_duplex != phy_dev->duplex) {
fec_restart(ndev, phy_dev->duplex);
+ netif_wake_queue(ndev);
status_change = 1;
}
}
@@ -1118,6 +1117,13 @@ static int fec_enet_alloc_buffers(struct net_device *ndev)
bdp = fep->tx_bd_base;
for (i = 0; i < TX_RING_SIZE; i++) {
fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
+ if(!fep->tx_bounce[i]) {
+ for(j = 0; j < i; j++) {
+ kfree(fep->tx_bounce[j]);
+ }
+ fec_enet_free_buffers(ndev);
+ return -ENOMEM;
+ }
bdp->cbd_sc = 0;
bdp->cbd_bufaddr = 0;