aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/r6040.c53
1 files changed, 44 insertions, 9 deletions
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 0972152e5d28..4f2ebb2e71be 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -312,7 +312,7 @@ static void r6040_rx_buf_alloc(struct r6040_private *lp, struct net_device *dev)
312 lp->rx_insert_ptr = descptr; 312 lp->rx_insert_ptr = descptr;
313} 313}
314 314
315static void r6040_alloc_txbufs(struct net_device *dev) 315static void r6040_init_txbufs(struct net_device *dev)
316{ 316{
317 struct r6040_private *lp = netdev_priv(dev); 317 struct r6040_private *lp = netdev_priv(dev);
318 318
@@ -322,16 +322,39 @@ static void r6040_alloc_txbufs(struct net_device *dev)
322 r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT); 322 r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT);
323} 323}
324 324
325static void r6040_alloc_rxbufs(struct net_device *dev) 325static int r6040_alloc_rxbufs(struct net_device *dev)
326{ 326{
327 struct r6040_private *lp = netdev_priv(dev); 327 struct r6040_private *lp = netdev_priv(dev);
328 328 struct r6040_descriptor *desc;
329 lp->rx_free_desc = 0; 329 struct sk_buff *skb;
330 int rc;
330 331
331 lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring; 332 lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring;
332 r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT); 333 r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT);
333 334
334 r6040_rx_buf_alloc(lp, dev); 335 /* Allocate skbs for the rx descriptors */
336 desc = lp->rx_ring;
337 do {
338 skb = netdev_alloc_skb(dev, MAX_BUF_SIZE);
339 if (!skb) {
340 printk(KERN_ERR "%s: failed to alloc skb for rx\n", dev->name);
341 rc = -ENOMEM;
342 goto err_exit;
343 }
344 desc->skb_ptr = skb;
345 desc->buf = cpu_to_le32(pci_map_single(lp->pdev,
346 desc->skb_ptr->data,
347 MAX_BUF_SIZE, PCI_DMA_FROMDEVICE));
348 desc->status = 0x8000;
349 desc = desc->vndescp;
350 } while (desc != lp->rx_ring);
351
352 return 0;
353
354err_exit:
355 /* Deallocate all previously allocated skbs */
356 r6040_free_rxbufs(dev);
357 return rc;
335} 358}
336 359
337static void r6040_init_mac_regs(struct net_device *dev) 360static void r6040_init_mac_regs(struct net_device *dev)
@@ -697,14 +720,17 @@ static void r6040_poll_controller(struct net_device *dev)
697#endif 720#endif
698 721
699/* Init RDC MAC */ 722/* Init RDC MAC */
700static void r6040_up(struct net_device *dev) 723static int r6040_up(struct net_device *dev)
701{ 724{
702 struct r6040_private *lp = netdev_priv(dev); 725 struct r6040_private *lp = netdev_priv(dev);
703 void __iomem *ioaddr = lp->base; 726 void __iomem *ioaddr = lp->base;
727 int ret;
704 728
705 /* Initialise and alloc RX/TX buffers */ 729 /* Initialise and alloc RX/TX buffers */
706 r6040_alloc_txbufs(dev); 730 r6040_init_txbufs(dev);
707 r6040_alloc_rxbufs(dev); 731 ret = r6040_alloc_rxbufs(dev);
732 if (ret)
733 return ret;
708 734
709 /* Read the PHY ID */ 735 /* Read the PHY ID */
710 lp->switch_sig = r6040_phy_read(ioaddr, 0, 2); 736 lp->switch_sig = r6040_phy_read(ioaddr, 0, 2);
@@ -734,6 +760,8 @@ static void r6040_up(struct net_device *dev)
734 760
735 /* Initialize all MAC registers */ 761 /* Initialize all MAC registers */
736 r6040_init_mac_regs(dev); 762 r6040_init_mac_regs(dev);
763
764 return 0;
737} 765}
738 766
739/* 767/*
@@ -812,7 +840,14 @@ static int r6040_open(struct net_device *dev)
812 return -ENOMEM; 840 return -ENOMEM;
813 } 841 }
814 842
815 r6040_up(dev); 843 ret = r6040_up(dev);
844 if (ret) {
845 pci_free_consistent(lp->pdev, TX_DESC_SIZE, lp->tx_ring,
846 lp->tx_ring_dma);
847 pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring,
848 lp->rx_ring_dma);
849 return ret;
850 }
816 851
817 napi_enable(&lp->napi); 852 napi_enable(&lp->napi);
818 netif_start_queue(dev); 853 netif_start_queue(dev);