1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#include <linux/platform_device.h>
34#include <linux/pci.h>
35#include <uapi/rdma/hns-abi.h>
36#include "hns_roce_device.h"
37
38static int hns_roce_pd_alloc(struct hns_roce_dev *hr_dev, unsigned long *pdn)
39{
40 return hns_roce_bitmap_alloc(&hr_dev->pd_bitmap, pdn);
41}
42
43static void hns_roce_pd_free(struct hns_roce_dev *hr_dev, unsigned long pdn)
44{
45 hns_roce_bitmap_free(&hr_dev->pd_bitmap, pdn, BITMAP_NO_RR);
46}
47
48int hns_roce_init_pd_table(struct hns_roce_dev *hr_dev)
49{
50 return hns_roce_bitmap_init(&hr_dev->pd_bitmap, hr_dev->caps.num_pds,
51 hr_dev->caps.num_pds - 1,
52 hr_dev->caps.reserved_pds, 0);
53}
54
55void hns_roce_cleanup_pd_table(struct hns_roce_dev *hr_dev)
56{
57 hns_roce_bitmap_cleanup(&hr_dev->pd_bitmap);
58}
59
60struct ib_pd *hns_roce_alloc_pd(struct ib_device *ib_dev,
61 struct ib_ucontext *context,
62 struct ib_udata *udata)
63{
64 struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev);
65 struct device *dev = hr_dev->dev;
66 struct hns_roce_pd *pd;
67 int ret;
68
69 pd = kmalloc(sizeof(*pd), GFP_KERNEL);
70 if (!pd)
71 return ERR_PTR(-ENOMEM);
72
73 ret = hns_roce_pd_alloc(to_hr_dev(ib_dev), &pd->pdn);
74 if (ret) {
75 kfree(pd);
76 dev_err(dev, "[alloc_pd]hns_roce_pd_alloc failed!\n");
77 return ERR_PTR(ret);
78 }
79
80 if (context) {
81 struct hns_roce_ib_alloc_pd_resp uresp = {.pdn = pd->pdn};
82
83 if (ib_copy_to_udata(udata, &uresp, sizeof(uresp))) {
84 hns_roce_pd_free(to_hr_dev(ib_dev), pd->pdn);
85 dev_err(dev, "[alloc_pd]ib_copy_to_udata failed!\n");
86 kfree(pd);
87 return ERR_PTR(-EFAULT);
88 }
89 }
90
91 return &pd->ibpd;
92}
93EXPORT_SYMBOL_GPL(hns_roce_alloc_pd);
94
95int hns_roce_dealloc_pd(struct ib_pd *pd)
96{
97 hns_roce_pd_free(to_hr_dev(pd->device), to_hr_pd(pd)->pdn);
98 kfree(to_hr_pd(pd));
99
100 return 0;
101}
102EXPORT_SYMBOL_GPL(hns_roce_dealloc_pd);
103
104int hns_roce_uar_alloc(struct hns_roce_dev *hr_dev, struct hns_roce_uar *uar)
105{
106 struct resource *res;
107 int ret = 0;
108
109
110 ret = hns_roce_bitmap_alloc(&hr_dev->uar_table.bitmap, &uar->index);
111 if (ret == -1)
112 return -ENOMEM;
113
114 if (uar->index > 0)
115 uar->index = (uar->index - 1) %
116 (hr_dev->caps.phy_num_uars - 1) + 1;
117
118 if (!dev_is_pci(hr_dev->dev)) {
119 res = platform_get_resource(hr_dev->pdev, IORESOURCE_MEM, 0);
120 if (!res) {
121 dev_err(&hr_dev->pdev->dev, "memory resource not found!\n");
122 return -EINVAL;
123 }
124 uar->pfn = ((res->start) >> PAGE_SHIFT) + uar->index;
125 } else {
126 uar->pfn = ((pci_resource_start(hr_dev->pci_dev, 2))
127 >> PAGE_SHIFT);
128 }
129
130 return 0;
131}
132
133void hns_roce_uar_free(struct hns_roce_dev *hr_dev, struct hns_roce_uar *uar)
134{
135 hns_roce_bitmap_free(&hr_dev->uar_table.bitmap, uar->index,
136 BITMAP_NO_RR);
137}
138
139int hns_roce_init_uar_table(struct hns_roce_dev *hr_dev)
140{
141 return hns_roce_bitmap_init(&hr_dev->uar_table.bitmap,
142 hr_dev->caps.num_uars,
143 hr_dev->caps.num_uars - 1,
144 hr_dev->caps.reserved_uars, 0);
145}
146
147void hns_roce_cleanup_uar_table(struct hns_roce_dev *hr_dev)
148{
149 hns_roce_bitmap_cleanup(&hr_dev->uar_table.bitmap);
150}
151