Commit | Line | Data |
---|---|---|
9a443537 | 1 | /* |
2 | * Copyright (c) 2016 Hisilicon Limited. | |
3 | * | |
4 | * This software is available to you under a choice of one of two | |
5 | * licenses. You may choose to be licensed under the terms of the GNU | |
6 | * General Public License (GPL) Version 2, available from the file | |
7 | * COPYING in the main directory of this source tree, or the | |
8 | * OpenIB.org BSD license below: | |
9 | * | |
10 | * Redistribution and use in source and binary forms, with or | |
11 | * without modification, are permitted provided that the following | |
12 | * conditions are met: | |
13 | * | |
14 | * - Redistributions of source code must retain the above | |
15 | * copyright notice, this list of conditions and the following | |
16 | * disclaimer. | |
17 | * | |
18 | * - Redistributions in binary form must reproduce the above | |
19 | * copyright notice, this list of conditions and the following | |
20 | * disclaimer in the documentation and/or other materials | |
21 | * provided with the distribution. | |
22 | * | |
23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
24 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
25 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
26 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
27 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
28 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
29 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
30 | * SOFTWARE. | |
31 | */ | |
32 | ||
7afddafa | 33 | #include <linux/pci.h> |
9a443537 | 34 | #include "hns_roce_device.h" |
35 | ||
645f0593 | 36 | void hns_roce_init_pd_table(struct hns_roce_dev *hr_dev) |
9a443537 | 37 | { |
645f0593 | 38 | struct hns_roce_ida *pd_ida = &hr_dev->pd_ida; |
9a443537 | 39 | |
645f0593 YL |
40 | ida_init(&pd_ida->ida); |
41 | pd_ida->max = hr_dev->caps.num_pds - 1; | |
42 | pd_ida->min = hr_dev->caps.reserved_pds; | |
9a443537 | 43 | } |
44 | ||
ff23dfa1 | 45 | int hns_roce_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata) |
9a443537 | 46 | { |
21a428a0 | 47 | struct ib_device *ib_dev = ibpd->device; |
645f0593 YL |
48 | struct hns_roce_dev *hr_dev = to_hr_dev(ib_dev); |
49 | struct hns_roce_ida *pd_ida = &hr_dev->pd_ida; | |
21a428a0 | 50 | struct hns_roce_pd *pd = to_hr_pd(ibpd); |
645f0593 YL |
51 | int ret = 0; |
52 | int id; | |
9a443537 | 53 | |
645f0593 YL |
54 | id = ida_alloc_range(&pd_ida->ida, pd_ida->min, pd_ida->max, |
55 | GFP_KERNEL); | |
56 | if (id < 0) { | |
57 | ibdev_err(ib_dev, "failed to alloc pd, id = %d.\n", id); | |
58 | return -ENOMEM; | |
9a443537 | 59 | } |
645f0593 | 60 | pd->pdn = (unsigned long)id; |
9a443537 | 61 | |
ff23dfa1 | 62 | if (udata) { |
1c0ca9cd | 63 | struct hns_roce_ib_alloc_pd_resp resp = {.pdn = pd->pdn}; |
633fb4d9 | 64 | |
1c0ca9cd WL |
65 | ret = ib_copy_to_udata(udata, &resp, |
66 | min(udata->outlen, sizeof(resp))); | |
67 | if (ret) { | |
645f0593 | 68 | ida_free(&pd_ida->ida, id); |
1c0ca9cd | 69 | ibdev_err(ib_dev, "failed to copy to udata, ret = %d\n", ret); |
9a443537 | 70 | } |
71 | } | |
72 | ||
1c0ca9cd | 73 | return ret; |
9a443537 | 74 | } |
75 | ||
91a7c58f | 76 | int hns_roce_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata) |
9a443537 | 77 | { |
645f0593 YL |
78 | struct hns_roce_dev *hr_dev = to_hr_dev(pd->device); |
79 | ||
80 | ida_free(&hr_dev->pd_ida.ida, (int)to_hr_pd(pd)->pdn); | |
81 | ||
91a7c58f | 82 | return 0; |
9a443537 | 83 | } |
84 | ||
85 | int hns_roce_uar_alloc(struct hns_roce_dev *hr_dev, struct hns_roce_uar *uar) | |
86 | { | |
8feafd90 | 87 | struct hns_roce_ida *uar_ida = &hr_dev->uar_ida; |
8feafd90 | 88 | int id; |
9a443537 | 89 | |
90 | /* Using bitmap to manager UAR index */ | |
8feafd90 YL |
91 | id = ida_alloc_range(&uar_ida->ida, uar_ida->min, uar_ida->max, |
92 | GFP_KERNEL); | |
93 | if (id < 0) { | |
94 | ibdev_err(&hr_dev->ib_dev, "failed to alloc uar id(%d).\n", id); | |
9a443537 | 95 | return -ENOMEM; |
8feafd90 YL |
96 | } |
97 | uar->logic_idx = (unsigned long)id; | |
9a443537 | 98 | |
5b6eb54f WHX |
99 | if (uar->logic_idx > 0 && hr_dev->caps.phy_num_uars > 1) |
100 | uar->index = (uar->logic_idx - 1) % | |
b280db52 | 101 | (hr_dev->caps.phy_num_uars - 1) + 1; |
5b6eb54f WHX |
102 | else |
103 | uar->index = 0; | |
9a443537 | 104 | |
38d22088 CT |
105 | uar->pfn = ((pci_resource_start(hr_dev->pci_dev, 2)) >> PAGE_SHIFT); |
106 | if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_DIRECT_WQE) | |
107 | hr_dev->dwqe_page = pci_resource_start(hr_dev->pci_dev, 4); | |
9a443537 | 108 | |
109 | return 0; | |
110 | } | |
111 | ||
8feafd90 | 112 | void hns_roce_init_uar_table(struct hns_roce_dev *hr_dev) |
9a443537 | 113 | { |
8feafd90 | 114 | struct hns_roce_ida *uar_ida = &hr_dev->uar_ida; |
9a443537 | 115 | |
8feafd90 YL |
116 | ida_init(&uar_ida->ida); |
117 | uar_ida->max = hr_dev->caps.num_uars - 1; | |
118 | uar_ida->min = hr_dev->caps.reserved_uars; | |
9a443537 | 119 | } |
32548870 WL |
120 | |
121 | static int hns_roce_xrcd_alloc(struct hns_roce_dev *hr_dev, u32 *xrcdn) | |
122 | { | |
da43b7be YL |
123 | struct hns_roce_ida *xrcd_ida = &hr_dev->xrcd_ida; |
124 | int id; | |
783cf673 | 125 | |
da43b7be YL |
126 | id = ida_alloc_range(&xrcd_ida->ida, xrcd_ida->min, xrcd_ida->max, |
127 | GFP_KERNEL); | |
128 | if (id < 0) { | |
129 | ibdev_err(&hr_dev->ib_dev, "failed to alloc xrcdn(%d).\n", id); | |
130 | return -ENOMEM; | |
131 | } | |
132 | *xrcdn = (u32)id; | |
783cf673 WL |
133 | |
134 | return 0; | |
32548870 WL |
135 | } |
136 | ||
da43b7be | 137 | void hns_roce_init_xrcd_table(struct hns_roce_dev *hr_dev) |
32548870 | 138 | { |
da43b7be | 139 | struct hns_roce_ida *xrcd_ida = &hr_dev->xrcd_ida; |
32548870 | 140 | |
da43b7be YL |
141 | ida_init(&xrcd_ida->ida); |
142 | xrcd_ida->max = hr_dev->caps.num_xrcds - 1; | |
143 | xrcd_ida->min = hr_dev->caps.reserved_xrcds; | |
32548870 WL |
144 | } |
145 | ||
146 | int hns_roce_alloc_xrcd(struct ib_xrcd *ib_xrcd, struct ib_udata *udata) | |
147 | { | |
148 | struct hns_roce_dev *hr_dev = to_hr_dev(ib_xrcd->device); | |
149 | struct hns_roce_xrcd *xrcd = to_hr_xrcd(ib_xrcd); | |
150 | int ret; | |
151 | ||
152 | if (!(hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_XRC)) | |
153 | return -EINVAL; | |
154 | ||
155 | ret = hns_roce_xrcd_alloc(hr_dev, &xrcd->xrcdn); | |
da43b7be | 156 | if (ret) |
32548870 | 157 | return ret; |
32548870 WL |
158 | |
159 | return 0; | |
160 | } | |
161 | ||
162 | int hns_roce_dealloc_xrcd(struct ib_xrcd *ib_xrcd, struct ib_udata *udata) | |
163 | { | |
da43b7be YL |
164 | struct hns_roce_dev *hr_dev = to_hr_dev(ib_xrcd->device); |
165 | u32 xrcdn = to_hr_xrcd(ib_xrcd)->xrcdn; | |
166 | ||
167 | ida_free(&hr_dev->xrcd_ida.ida, (int)xrcdn); | |
32548870 WL |
168 | |
169 | return 0; | |
170 | } |