diff options
-rw-r--r-- | drivers/net/r6040.c | 53 |
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 | ||
315 | static void r6040_alloc_txbufs(struct net_device *dev) | 315 | static 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 | ||
325 | static void r6040_alloc_rxbufs(struct net_device *dev) | 325 | static 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 | |||
354 | err_exit: | ||
355 | /* Deallocate all previously allocated skbs */ | ||
356 | r6040_free_rxbufs(dev); | ||
357 | return rc; | ||
335 | } | 358 | } |
336 | 359 | ||
337 | static void r6040_init_mac_regs(struct net_device *dev) | 360 | static 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 */ |
700 | static void r6040_up(struct net_device *dev) | 723 | static 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); |