Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
net
ethernet
mellanox
mlx4
pd.c
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
3
* Copyright (c) 2005 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/init.h
>
35
#include <linux/errno.h>
36
#include <linux/export.h>
37
#include <
linux/io-mapping.h
>
38
39
#include <asm/page.h>
40
41
#include "
mlx4.h
"
42
#include "
icm.h
"
43
44
enum
{
45
MLX4_NUM_RESERVED_UARS
= 8
46
};
47
48
int
mlx4_pd_alloc
(
struct
mlx4_dev
*
dev
,
u32
*pdn)
49
{
50
struct
mlx4_priv
*
priv
=
mlx4_priv
(dev);
51
52
*pdn =
mlx4_bitmap_alloc
(&priv->
pd_bitmap
);
53
if
(*pdn == -1)
54
return
-
ENOMEM
;
55
56
return
0;
57
}
58
EXPORT_SYMBOL_GPL
(
mlx4_pd_alloc
);
59
60
void
mlx4_pd_free
(
struct
mlx4_dev
*
dev
,
u32
pdn)
61
{
62
mlx4_bitmap_free
(&
mlx4_priv
(dev)->
pd_bitmap
, pdn);
63
}
64
EXPORT_SYMBOL_GPL
(
mlx4_pd_free
);
65
66
int
__mlx4_xrcd_alloc
(
struct
mlx4_dev
*
dev
,
u32
*xrcdn)
67
{
68
struct
mlx4_priv
*
priv
=
mlx4_priv
(dev);
69
70
*xrcdn =
mlx4_bitmap_alloc
(&priv->
xrcd_bitmap
);
71
if
(*xrcdn == -1)
72
return
-
ENOMEM
;
73
74
return
0;
75
}
76
77
int
mlx4_xrcd_alloc
(
struct
mlx4_dev
*
dev
,
u32
*xrcdn)
78
{
79
u64
out_param;
80
int
err
;
81
82
if
(mlx4_is_mfunc(dev)) {
83
err = mlx4_cmd_imm(dev, 0, &out_param,
84
RES_XRCD
,
RES_OP_RESERVE
,
85
MLX4_CMD_ALLOC_RES
,
86
MLX4_CMD_TIME_CLASS_A
,
MLX4_CMD_WRAPPED
);
87
if
(err)
88
return
err
;
89
90
*xrcdn = get_param_l(&out_param);
91
return
0;
92
}
93
return
__mlx4_xrcd_alloc
(dev, xrcdn);
94
}
95
EXPORT_SYMBOL_GPL
(
mlx4_xrcd_alloc
);
96
97
void
__mlx4_xrcd_free
(
struct
mlx4_dev
*
dev
,
u32
xrcdn)
98
{
99
mlx4_bitmap_free
(&
mlx4_priv
(dev)->
xrcd_bitmap
, xrcdn);
100
}
101
102
void
mlx4_xrcd_free
(
struct
mlx4_dev
*
dev
,
u32
xrcdn)
103
{
104
u64
in_param;
105
int
err
;
106
107
if
(mlx4_is_mfunc(dev)) {
108
set_param_l(&in_param, xrcdn);
109
err =
mlx4_cmd
(dev, in_param,
RES_XRCD
,
110
RES_OP_RESERVE
,
MLX4_CMD_FREE_RES
,
111
MLX4_CMD_TIME_CLASS_A
,
MLX4_CMD_WRAPPED
);
112
if
(err)
113
mlx4_warn
(dev,
"Failed to release xrcdn %d\n"
, xrcdn);
114
}
else
115
__mlx4_xrcd_free
(dev, xrcdn);
116
}
117
EXPORT_SYMBOL_GPL
(
mlx4_xrcd_free
);
118
119
int
mlx4_init_pd_table
(
struct
mlx4_dev
*
dev
)
120
{
121
struct
mlx4_priv
*
priv
=
mlx4_priv
(dev);
122
123
return
mlx4_bitmap_init
(&priv->
pd_bitmap
, dev->
caps
.num_pds,
124
(1 <<
NOT_MASKED_PD_BITS
) - 1,
125
dev->
caps
.reserved_pds, 0);
126
}
127
128
void
mlx4_cleanup_pd_table
(
struct
mlx4_dev
*
dev
)
129
{
130
mlx4_bitmap_cleanup
(&
mlx4_priv
(dev)->
pd_bitmap
);
131
}
132
133
int
mlx4_init_xrcd_table
(
struct
mlx4_dev
*
dev
)
134
{
135
struct
mlx4_priv
*
priv
=
mlx4_priv
(dev);
136
137
return
mlx4_bitmap_init
(&priv->
xrcd_bitmap
, (1 << 16),
138
(1 << 16) - 1, dev->
caps
.reserved_xrcds + 1, 0);
139
}
140
141
void
mlx4_cleanup_xrcd_table
(
struct
mlx4_dev
*
dev
)
142
{
143
mlx4_bitmap_cleanup
(&
mlx4_priv
(dev)->
xrcd_bitmap
);
144
}
145
146
int
mlx4_uar_alloc
(
struct
mlx4_dev
*
dev
,
struct
mlx4_uar
*uar)
147
{
148
int
offset
;
149
150
uar->
index
=
mlx4_bitmap_alloc
(&
mlx4_priv
(dev)->
uar_table
.bitmap);
151
if
(uar->
index
== -1)
152
return
-
ENOMEM
;
153
154
if
(mlx4_is_slave(dev))
155
offset = uar->
index
% ((
int
)
pci_resource_len
(dev->
pdev
, 2) /
156
dev->
caps
.uar_page_size);
157
else
158
offset = uar->
index
;
159
uar->
pfn
= (
pci_resource_start
(dev->
pdev
, 2) >>
PAGE_SHIFT
) + offset;
160
uar->
map
=
NULL
;
161
return
0;
162
}
163
EXPORT_SYMBOL_GPL
(
mlx4_uar_alloc
);
164
165
void
mlx4_uar_free
(
struct
mlx4_dev
*
dev
,
struct
mlx4_uar
*uar)
166
{
167
mlx4_bitmap_free
(&
mlx4_priv
(dev)->
uar_table
.bitmap, uar->
index
);
168
}
169
EXPORT_SYMBOL_GPL
(
mlx4_uar_free
);
170
171
int
mlx4_bf_alloc
(
struct
mlx4_dev
*
dev
,
struct
mlx4_bf
*
bf
)
172
{
173
struct
mlx4_priv
*
priv
=
mlx4_priv
(dev);
174
struct
mlx4_uar
*uar;
175
int
err
= 0;
176
int
idx
;
177
178
if
(!priv->
bf_mapping
)
179
return
-
ENOMEM
;
180
181
mutex_lock
(&priv->
bf_mutex
);
182
if
(!list_empty(&priv->
bf_list
))
183
uar =
list_entry
(priv->
bf_list
.next,
struct
mlx4_uar
,
bf_list
);
184
else
{
185
if
(
mlx4_bitmap_avail
(&priv->
uar_table
.bitmap) <
MLX4_NUM_RESERVED_UARS
) {
186
err = -
ENOMEM
;
187
goto
out
;
188
}
189
uar =
kmalloc
(
sizeof
*uar,
GFP_KERNEL
);
190
if
(!uar) {
191
err = -
ENOMEM
;
192
goto
out
;
193
}
194
err =
mlx4_uar_alloc
(dev, uar);
195
if
(err)
196
goto
free_kmalloc;
197
198
uar->
map
=
ioremap
(uar->
pfn
<<
PAGE_SHIFT
,
PAGE_SIZE
);
199
if
(!uar->
map
) {
200
err = -
ENOMEM
;
201
goto
free_uar;
202
}
203
204
uar->
bf_map
= io_mapping_map_wc(priv->
bf_mapping
, uar->
index
<<
PAGE_SHIFT
);
205
if
(!uar->
bf_map
) {
206
err = -
ENOMEM
;
207
goto
unamp_uar;
208
}
209
uar->
free_bf_bmap
= 0;
210
list_add(&uar->
bf_list
, &priv->
bf_list
);
211
}
212
213
bf->
uar
= uar;
214
idx =
ffz
(uar->
free_bf_bmap
);
215
uar->
free_bf_bmap
|= 1 <<
idx
;
216
bf->
uar
= uar;
217
bf->
offset
= 0;
218
bf->
buf_size
= dev->
caps
.bf_reg_size / 2;
219
bf->
reg
= uar->
bf_map
+ idx * dev->
caps
.bf_reg_size;
220
if
(uar->
free_bf_bmap
== (1 << dev->
caps
.bf_regs_per_page) - 1)
221
list_del_init(&uar->
bf_list
);
222
223
goto
out
;
224
225
unamp_uar:
226
bf->
uar
=
NULL
;
227
iounmap
(uar->
map
);
228
229
free_uar:
230
mlx4_uar_free
(dev, uar);
231
232
free_kmalloc:
233
kfree
(uar);
234
235
out
:
236
mutex_unlock
(&priv->
bf_mutex
);
237
return
err
;
238
}
239
EXPORT_SYMBOL_GPL
(
mlx4_bf_alloc
);
240
241
void
mlx4_bf_free
(
struct
mlx4_dev
*
dev
,
struct
mlx4_bf
*
bf
)
242
{
243
struct
mlx4_priv
*
priv
=
mlx4_priv
(dev);
244
int
idx
;
245
246
if
(!bf->
uar
|| !bf->
uar
->bf_map)
247
return
;
248
249
mutex_lock
(&priv->
bf_mutex
);
250
idx = (bf->
reg
- bf->
uar
->bf_map) / dev->
caps
.bf_reg_size;
251
bf->
uar
->free_bf_bmap &= ~(1 << idx);
252
if
(!bf->
uar
->free_bf_bmap) {
253
if
(!list_empty(&bf->
uar
->bf_list))
254
list_del
(&bf->
uar
->bf_list);
255
256
io_mapping_unmap(bf->
uar
->bf_map);
257
iounmap
(bf->
uar
->map);
258
mlx4_uar_free
(dev, bf->
uar
);
259
kfree
(bf->
uar
);
260
}
else
if
(list_empty(&bf->
uar
->bf_list))
261
list_add(&bf->
uar
->bf_list, &priv->
bf_list
);
262
263
mutex_unlock
(&priv->
bf_mutex
);
264
}
265
EXPORT_SYMBOL_GPL
(
mlx4_bf_free
);
266
267
int
mlx4_init_uar_table
(
struct
mlx4_dev
*
dev
)
268
{
269
if
(dev->
caps
.num_uars <= 128) {
270
mlx4_err
(dev,
"Only %d UAR pages (need more than 128)\n"
,
271
dev->
caps
.num_uars);
272
mlx4_err
(dev,
"Increase firmware log2_uar_bar_megabytes?\n"
);
273
return
-
ENODEV
;
274
}
275
276
return
mlx4_bitmap_init
(&
mlx4_priv
(dev)->
uar_table
.bitmap,
277
dev->
caps
.num_uars, dev->
caps
.num_uars - 1,
278
dev->
caps
.reserved_uars, 0);
279
}
280
281
void
mlx4_cleanup_uar_table
(
struct
mlx4_dev
*
dev
)
282
{
283
mlx4_bitmap_cleanup
(&
mlx4_priv
(dev)->
uar_table
.bitmap);
284
}
Generated on Thu Jan 10 2013 13:26:51 for Linux Kernel by
1.8.2