Skip to content

Commit 9a44353

Browse files
oulijundledford
authored andcommitted
IB/hns: Add driver files for hns RoCE driver
These are the various new source code files for the Hisilicon RoCE driver for ARM architecture. Signed-off-by: Wei Hu <xavier.huwei@huawei.com> Signed-off-by: Nenglong Zhao <zhaonenglong@hisilicon.com> Signed-off-by: Lijun Ou <oulijun@huawei.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
1 parent 69bafce commit 9a44353

18 files changed

Lines changed: 10324 additions & 0 deletions
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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+
33+
#include <linux/platform_device.h>
34+
#include <rdma/ib_addr.h>
35+
#include <rdma/ib_cache.h>
36+
#include "hns_roce_device.h"
37+
38+
#define HNS_ROCE_PORT_NUM_SHIFT 24
39+
#define HNS_ROCE_VLAN_SL_BIT_MASK 7
40+
#define HNS_ROCE_VLAN_SL_SHIFT 13
41+
42+
struct ib_ah *hns_roce_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *ah_attr)
43+
{
44+
struct hns_roce_dev *hr_dev = to_hr_dev(ibpd->device);
45+
struct device *dev = &hr_dev->pdev->dev;
46+
struct ib_gid_attr gid_attr;
47+
struct hns_roce_ah *ah;
48+
u16 vlan_tag = 0xffff;
49+
struct in6_addr in6;
50+
union ib_gid sgid;
51+
int ret;
52+
53+
ah = kzalloc(sizeof(*ah), GFP_ATOMIC);
54+
if (!ah)
55+
return ERR_PTR(-ENOMEM);
56+
57+
/* Get mac address */
58+
memcpy(&in6, ah_attr->grh.dgid.raw, sizeof(ah_attr->grh.dgid.raw));
59+
if (rdma_is_multicast_addr(&in6))
60+
rdma_get_mcast_mac(&in6, ah->av.mac);
61+
else
62+
memcpy(ah->av.mac, ah_attr->dmac, sizeof(ah_attr->dmac));
63+
64+
/* Get source gid */
65+
ret = ib_get_cached_gid(ibpd->device, ah_attr->port_num,
66+
ah_attr->grh.sgid_index, &sgid, &gid_attr);
67+
if (ret) {
68+
dev_err(dev, "get sgid failed! ret = %d\n", ret);
69+
kfree(ah);
70+
return ERR_PTR(ret);
71+
}
72+
73+
if (gid_attr.ndev) {
74+
if (is_vlan_dev(gid_attr.ndev))
75+
vlan_tag = vlan_dev_vlan_id(gid_attr.ndev);
76+
dev_put(gid_attr.ndev);
77+
}
78+
79+
if (vlan_tag < 0x1000)
80+
vlan_tag |= (ah_attr->sl & HNS_ROCE_VLAN_SL_BIT_MASK) <<
81+
HNS_ROCE_VLAN_SL_SHIFT;
82+
83+
ah->av.port_pd = cpu_to_be32(to_hr_pd(ibpd)->pdn | (ah_attr->port_num <<
84+
HNS_ROCE_PORT_NUM_SHIFT));
85+
ah->av.gid_index = ah_attr->grh.sgid_index;
86+
ah->av.vlan = cpu_to_le16(vlan_tag);
87+
dev_dbg(dev, "gid_index = 0x%x,vlan = 0x%x\n", ah->av.gid_index,
88+
ah->av.vlan);
89+
90+
if (ah_attr->static_rate)
91+
ah->av.stat_rate = IB_RATE_10_GBPS;
92+
93+
memcpy(ah->av.dgid, ah_attr->grh.dgid.raw, HNS_ROCE_GID_SIZE);
94+
ah->av.sl_tclass_flowlabel = cpu_to_le32(ah_attr->sl <<
95+
HNS_ROCE_SL_SHIFT);
96+
97+
return &ah->ibah;
98+
}
99+
100+
int hns_roce_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr)
101+
{
102+
struct hns_roce_ah *ah = to_hr_ah(ibah);
103+
104+
memset(ah_attr, 0, sizeof(*ah_attr));
105+
106+
ah_attr->sl = le32_to_cpu(ah->av.sl_tclass_flowlabel) >>
107+
HNS_ROCE_SL_SHIFT;
108+
ah_attr->port_num = le32_to_cpu(ah->av.port_pd) >>
109+
HNS_ROCE_PORT_NUM_SHIFT;
110+
ah_attr->static_rate = ah->av.stat_rate;
111+
ah_attr->ah_flags = IB_AH_GRH;
112+
ah_attr->grh.traffic_class = le32_to_cpu(ah->av.sl_tclass_flowlabel) >>
113+
HNS_ROCE_TCLASS_SHIFT;
114+
ah_attr->grh.flow_label = le32_to_cpu(ah->av.sl_tclass_flowlabel) &
115+
HNS_ROCE_FLOW_LABLE_MASK;
116+
ah_attr->grh.hop_limit = ah->av.hop_limit;
117+
ah_attr->grh.sgid_index = ah->av.gid_index;
118+
memcpy(ah_attr->grh.dgid.raw, ah->av.dgid, HNS_ROCE_GID_SIZE);
119+
120+
return 0;
121+
}
122+
123+
int hns_roce_destroy_ah(struct ib_ah *ah)
124+
{
125+
kfree(to_hr_ah(ah));
126+
127+
return 0;
128+
}
Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
/*
2+
* Copyright (c) 2016 Hisilicon Limited.
3+
* Copyright (c) 2007, 2008 Mellanox Technologies. All rights reserved.
4+
*
5+
* This software is available to you under a choice of one of two
6+
* licenses. You may choose to be licensed under the terms of the GNU
7+
* General Public License (GPL) Version 2, available from the file
8+
* COPYING in the main directory of this source tree, or the
9+
* OpenIB.org BSD license below:
10+
*
11+
* Redistribution and use in source and binary forms, with or
12+
* without modification, are permitted provided that the following
13+
* conditions are met:
14+
*
15+
* - Redistributions of source code must retain the above
16+
* copyright notice, this list of conditions and the following
17+
* disclaimer.
18+
*
19+
* - Redistributions in binary form must reproduce the above
20+
* copyright notice, this list of conditions and the following
21+
* disclaimer in the documentation and/or other materials
22+
* provided with the distribution.
23+
*
24+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28+
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29+
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31+
* SOFTWARE.
32+
*/
33+
34+
#include <linux/platform_device.h>
35+
#include "hns_roce_device.h"
36+
37+
int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, unsigned long *obj)
38+
{
39+
int ret = 0;
40+
41+
spin_lock(&bitmap->lock);
42+
*obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last);
43+
if (*obj >= bitmap->max) {
44+
bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
45+
& bitmap->mask;
46+
*obj = find_first_zero_bit(bitmap->table, bitmap->max);
47+
}
48+
49+
if (*obj < bitmap->max) {
50+
set_bit(*obj, bitmap->table);
51+
bitmap->last = (*obj + 1);
52+
if (bitmap->last == bitmap->max)
53+
bitmap->last = 0;
54+
*obj |= bitmap->top;
55+
} else {
56+
ret = -1;
57+
}
58+
59+
spin_unlock(&bitmap->lock);
60+
61+
return ret;
62+
}
63+
64+
void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, unsigned long obj)
65+
{
66+
hns_roce_bitmap_free_range(bitmap, obj, 1);
67+
}
68+
69+
int hns_roce_bitmap_alloc_range(struct hns_roce_bitmap *bitmap, int cnt,
70+
int align, unsigned long *obj)
71+
{
72+
int ret = 0;
73+
int i;
74+
75+
if (likely(cnt == 1 && align == 1))
76+
return hns_roce_bitmap_alloc(bitmap, obj);
77+
78+
spin_lock(&bitmap->lock);
79+
80+
*obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max,
81+
bitmap->last, cnt, align - 1);
82+
if (*obj >= bitmap->max) {
83+
bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
84+
& bitmap->mask;
85+
*obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max, 0,
86+
cnt, align - 1);
87+
}
88+
89+
if (*obj < bitmap->max) {
90+
for (i = 0; i < cnt; i++)
91+
set_bit(*obj + i, bitmap->table);
92+
93+
if (*obj == bitmap->last) {
94+
bitmap->last = (*obj + cnt);
95+
if (bitmap->last >= bitmap->max)
96+
bitmap->last = 0;
97+
}
98+
*obj |= bitmap->top;
99+
} else {
100+
ret = -1;
101+
}
102+
103+
spin_unlock(&bitmap->lock);
104+
105+
return ret;
106+
}
107+
108+
void hns_roce_bitmap_free_range(struct hns_roce_bitmap *bitmap,
109+
unsigned long obj, int cnt)
110+
{
111+
int i;
112+
113+
obj &= bitmap->max + bitmap->reserved_top - 1;
114+
115+
spin_lock(&bitmap->lock);
116+
for (i = 0; i < cnt; i++)
117+
clear_bit(obj + i, bitmap->table);
118+
119+
bitmap->last = min(bitmap->last, obj);
120+
bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top)
121+
& bitmap->mask;
122+
spin_unlock(&bitmap->lock);
123+
}
124+
125+
int hns_roce_bitmap_init(struct hns_roce_bitmap *bitmap, u32 num, u32 mask,
126+
u32 reserved_bot, u32 reserved_top)
127+
{
128+
u32 i;
129+
130+
if (num != roundup_pow_of_two(num))
131+
return -EINVAL;
132+
133+
bitmap->last = 0;
134+
bitmap->top = 0;
135+
bitmap->max = num - reserved_top;
136+
bitmap->mask = mask;
137+
bitmap->reserved_top = reserved_top;
138+
spin_lock_init(&bitmap->lock);
139+
bitmap->table = kcalloc(BITS_TO_LONGS(bitmap->max), sizeof(long),
140+
GFP_KERNEL);
141+
if (!bitmap->table)
142+
return -ENOMEM;
143+
144+
for (i = 0; i < reserved_bot; ++i)
145+
set_bit(i, bitmap->table);
146+
147+
return 0;
148+
}
149+
150+
void hns_roce_bitmap_cleanup(struct hns_roce_bitmap *bitmap)
151+
{
152+
kfree(bitmap->table);
153+
}
154+
155+
void hns_roce_buf_free(struct hns_roce_dev *hr_dev, u32 size,
156+
struct hns_roce_buf *buf)
157+
{
158+
int i;
159+
struct device *dev = &hr_dev->pdev->dev;
160+
u32 bits_per_long = BITS_PER_LONG;
161+
162+
if (buf->nbufs == 1) {
163+
dma_free_coherent(dev, size, buf->direct.buf, buf->direct.map);
164+
} else {
165+
if (bits_per_long == 64)
166+
vunmap(buf->direct.buf);
167+
168+
for (i = 0; i < buf->nbufs; ++i)
169+
if (buf->page_list[i].buf)
170+
dma_free_coherent(&hr_dev->pdev->dev, PAGE_SIZE,
171+
buf->page_list[i].buf,
172+
buf->page_list[i].map);
173+
kfree(buf->page_list);
174+
}
175+
}
176+
177+
int hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size, u32 max_direct,
178+
struct hns_roce_buf *buf)
179+
{
180+
int i = 0;
181+
dma_addr_t t;
182+
struct page **pages;
183+
struct device *dev = &hr_dev->pdev->dev;
184+
u32 bits_per_long = BITS_PER_LONG;
185+
186+
/* SQ/RQ buf lease than one page, SQ + RQ = 8K */
187+
if (size <= max_direct) {
188+
buf->nbufs = 1;
189+
/* Npages calculated by page_size */
190+
buf->npages = 1 << get_order(size);
191+
buf->page_shift = PAGE_SHIFT;
192+
/* MTT PA must be recorded in 4k alignment, t is 4k aligned */
193+
buf->direct.buf = dma_alloc_coherent(dev, size, &t, GFP_KERNEL);
194+
if (!buf->direct.buf)
195+
return -ENOMEM;
196+
197+
buf->direct.map = t;
198+
199+
while (t & ((1 << buf->page_shift) - 1)) {
200+
--buf->page_shift;
201+
buf->npages *= 2;
202+
}
203+
204+
memset(buf->direct.buf, 0, size);
205+
} else {
206+
buf->nbufs = (size + PAGE_SIZE - 1) / PAGE_SIZE;
207+
buf->npages = buf->nbufs;
208+
buf->page_shift = PAGE_SHIFT;
209+
buf->page_list = kcalloc(buf->nbufs, sizeof(*buf->page_list),
210+
GFP_KERNEL);
211+
212+
if (!buf->page_list)
213+
return -ENOMEM;
214+
215+
for (i = 0; i < buf->nbufs; ++i) {
216+
buf->page_list[i].buf = dma_alloc_coherent(dev,
217+
PAGE_SIZE, &t,
218+
GFP_KERNEL);
219+
220+
if (!buf->page_list[i].buf)
221+
goto err_free;
222+
223+
buf->page_list[i].map = t;
224+
memset(buf->page_list[i].buf, 0, PAGE_SIZE);
225+
}
226+
if (bits_per_long == 64) {
227+
pages = kmalloc_array(buf->nbufs, sizeof(*pages),
228+
GFP_KERNEL);
229+
if (!pages)
230+
goto err_free;
231+
232+
for (i = 0; i < buf->nbufs; ++i)
233+
pages[i] = virt_to_page(buf->page_list[i].buf);
234+
235+
buf->direct.buf = vmap(pages, buf->nbufs, VM_MAP,
236+
PAGE_KERNEL);
237+
kfree(pages);
238+
if (!buf->direct.buf)
239+
goto err_free;
240+
}
241+
}
242+
243+
return 0;
244+
245+
err_free:
246+
hns_roce_buf_free(hr_dev, size, buf);
247+
return -ENOMEM;
248+
}
249+
250+
void hns_roce_cleanup_bitmap(struct hns_roce_dev *hr_dev)
251+
{
252+
hns_roce_cleanup_qp_table(hr_dev);
253+
hns_roce_cleanup_cq_table(hr_dev);
254+
hns_roce_cleanup_mr_table(hr_dev);
255+
hns_roce_cleanup_pd_table(hr_dev);
256+
hns_roce_cleanup_uar_table(hr_dev);
257+
}

0 commit comments

Comments
 (0)