aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/cnic.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2012-09-08 02:01:01 -0400
committerDavid S. Miller <davem@davemloft.net>2012-09-10 15:48:20 -0400
commit74dd0c42093e0fd70ca7d901d18c2c01a6fd0fd3 (patch)
tree2c31343a45040002484627065622d375b6fa2cac /drivers/net/ethernet/broadcom/cnic.c
parentb6069a95706ca5738be3f5d90fd286cbd13ac695 (diff)
cnic: Add functions to allocate and free UIO rings
These functions are needed to free up memory when the rings are no longer needed. Reviewed-by: Eddie Wai <eddie.wai@broadcom.com> Reviewed-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/cnic.c')
-rw-r--r--drivers/net/ethernet/broadcom/cnic.c59
1 files changed, 40 insertions, 19 deletions
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
index 3b4fc61f24cf..ff3589405dce 100644
--- a/drivers/net/ethernet/broadcom/cnic.c
+++ b/drivers/net/ethernet/broadcom/cnic.c
@@ -823,10 +823,8 @@ static void cnic_free_context(struct cnic_dev *dev)
823 } 823 }
824} 824}
825 825
826static void __cnic_free_uio(struct cnic_uio_dev *udev) 826static void __cnic_free_uio_rings(struct cnic_uio_dev *udev)
827{ 827{
828 uio_unregister_device(&udev->cnic_uinfo);
829
830 if (udev->l2_buf) { 828 if (udev->l2_buf) {
831 dma_free_coherent(&udev->pdev->dev, udev->l2_buf_size, 829 dma_free_coherent(&udev->pdev->dev, udev->l2_buf_size,
832 udev->l2_buf, udev->l2_buf_map); 830 udev->l2_buf, udev->l2_buf_map);
@@ -839,6 +837,14 @@ static void __cnic_free_uio(struct cnic_uio_dev *udev)
839 udev->l2_ring = NULL; 837 udev->l2_ring = NULL;
840 } 838 }
841 839
840}
841
842static void __cnic_free_uio(struct cnic_uio_dev *udev)
843{
844 uio_unregister_device(&udev->cnic_uinfo);
845
846 __cnic_free_uio_rings(udev);
847
842 pci_dev_put(udev->pdev); 848 pci_dev_put(udev->pdev);
843 kfree(udev); 849 kfree(udev);
844} 850}
@@ -996,6 +1002,34 @@ static int cnic_alloc_kcq(struct cnic_dev *dev, struct kcq_info *info,
996 return 0; 1002 return 0;
997} 1003}
998 1004
1005static int __cnic_alloc_uio_rings(struct cnic_uio_dev *udev, int pages)
1006{
1007 struct cnic_local *cp = udev->dev->cnic_priv;
1008
1009 if (udev->l2_ring)
1010 return 0;
1011
1012 udev->l2_ring_size = pages * BCM_PAGE_SIZE;
1013 udev->l2_ring = dma_alloc_coherent(&udev->pdev->dev, udev->l2_ring_size,
1014 &udev->l2_ring_map,
1015 GFP_KERNEL | __GFP_COMP);
1016 if (!udev->l2_ring)
1017 return -ENOMEM;
1018
1019 udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size;
1020 udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size);
1021 udev->l2_buf = dma_alloc_coherent(&udev->pdev->dev, udev->l2_buf_size,
1022 &udev->l2_buf_map,
1023 GFP_KERNEL | __GFP_COMP);
1024 if (!udev->l2_buf) {
1025 __cnic_free_uio_rings(udev);
1026 return -ENOMEM;
1027 }
1028
1029 return 0;
1030
1031}
1032
999static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) 1033static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
1000{ 1034{
1001 struct cnic_local *cp = dev->cnic_priv; 1035 struct cnic_local *cp = dev->cnic_priv;
@@ -1020,20 +1054,9 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
1020 1054
1021 udev->dev = dev; 1055 udev->dev = dev;
1022 udev->pdev = dev->pcidev; 1056 udev->pdev = dev->pcidev;
1023 udev->l2_ring_size = pages * BCM_PAGE_SIZE;
1024 udev->l2_ring = dma_alloc_coherent(&udev->pdev->dev, udev->l2_ring_size,
1025 &udev->l2_ring_map,
1026 GFP_KERNEL | __GFP_COMP);
1027 if (!udev->l2_ring)
1028 goto err_udev;
1029 1057
1030 udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size; 1058 if (__cnic_alloc_uio_rings(udev, pages))
1031 udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size); 1059 goto err_udev;
1032 udev->l2_buf = dma_alloc_coherent(&udev->pdev->dev, udev->l2_buf_size,
1033 &udev->l2_buf_map,
1034 GFP_KERNEL | __GFP_COMP);
1035 if (!udev->l2_buf)
1036 goto err_dma;
1037 1060
1038 write_lock(&cnic_dev_lock); 1061 write_lock(&cnic_dev_lock);
1039 list_add(&udev->list, &cnic_udev_list); 1062 list_add(&udev->list, &cnic_udev_list);
@@ -1044,9 +1067,7 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
1044 cp->udev = udev; 1067 cp->udev = udev;
1045 1068
1046 return 0; 1069 return 0;
1047 err_dma: 1070
1048 dma_free_coherent(&udev->pdev->dev, udev->l2_ring_size,
1049 udev->l2_ring, udev->l2_ring_map);
1050 err_udev: 1071 err_udev:
1051 kfree(udev); 1072 kfree(udev);
1052 return -ENOMEM; 1073 return -ENOMEM;