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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
|
/*
* Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) 2005, 2006, 2007 Cisco Systems. All rights reserved.
* Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved.
* Copyright (c) 2004 Voltaire, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef MLX4_H
#define MLX4_H
#include <linux/mutex.h>
#include <linux/radix-tree.h>
#include <linux/timer.h>
#include <linux/mlx4/device.h>
#include <linux/mlx4/driver.h>
#include <linux/mlx4/doorbell.h>
#define DRV_NAME "mlx4_core"
#define PFX DRV_NAME ": "
#define DRV_VERSION "0.01"
#define DRV_RELDATE "May 1, 2007"
enum {
MLX4_HCR_BASE = 0x80680,
MLX4_HCR_SIZE = 0x0001c,
MLX4_CLR_INT_SIZE = 0x00008
};
enum {
MLX4_MGM_ENTRY_SIZE = 0x100,
MLX4_QP_PER_MGM = 4 * (MLX4_MGM_ENTRY_SIZE / 16 - 2),
MLX4_MTT_ENTRY_PER_SEG = 8
};
enum {
MLX4_EQ_ASYNC,
MLX4_EQ_COMP,
MLX4_NUM_EQ
};
enum {
MLX4_NUM_PDS = 1 << 15
};
enum {
MLX4_CMPT_TYPE_QP = 0,
MLX4_CMPT_TYPE_SRQ = 1,
MLX4_CMPT_TYPE_CQ = 2,
MLX4_CMPT_TYPE_EQ = 3,
MLX4_CMPT_NUM_TYPE
};
enum {
MLX4_CMPT_SHIFT = 24,
MLX4_NUM_CMPTS = MLX4_CMPT_NUM_TYPE << MLX4_CMPT_SHIFT
};
#ifdef CONFIG_MLX4_DEBUG
extern int mlx4_debug_level;
#define mlx4_dbg(mdev, format, arg...) \
do { \
if (mlx4_debug_level) \
dev_printk(KERN_DEBUG, &mdev->pdev->dev, format, ## arg); \
} while (0)
#else /* CONFIG_MLX4_DEBUG */
#define mlx4_dbg(mdev, format, arg...) do { (void) mdev; } while (0)
#endif /* CONFIG_MLX4_DEBUG */
#define mlx4_err(mdev, format, arg...) \
dev_err(&mdev->pdev->dev, format, ## arg)
#define mlx4_info(mdev, format, arg...) \
dev_info(&mdev->pdev->dev, format, ## arg)
#define mlx4_warn(mdev, format, arg...) \
dev_warn(&mdev->pdev->dev, format, ## arg)
struct mlx4_bitmap {
u32 last;
u32 top;
u32 max;
u32 mask;
spinlock_t lock;
unsigned long *table;
};
struct mlx4_buddy {
unsigned long **bits;
unsigned int *num_free;
int max_order;
spinlock_t lock;
};
struct mlx4_icm;
struct mlx4_icm_table {
u64 virt;
int num_icm;
int num_obj;
int obj_size;
int lowmem;
int coherent;
struct mutex mutex;
struct mlx4_icm **icm;
};
struct mlx4_eq {
struct mlx4_dev *dev;
void __iomem *doorbell;
int eqn;
u32 cons_index;
u16 irq;
u16 have_irq;
int nent;
struct mlx4_buf_list *page_list;
struct mlx4_mtt mtt;
};
struct mlx4_profile {
int num_qp;
int rdmarc_per_qp;
int num_srq;
int num_cq;
int num_mcg;
int num_mpt;
int num_mtt;
};
struct mlx4_fw {
u64 clr_int_base;
u64 catas_offset;
struct mlx4_icm *fw_icm;
struct mlx4_icm *aux_icm;
u32 catas_size;
u16 fw_pages;
u8 clr_int_bar;
u8 catas_bar;
};
struct mlx4_cmd {
struct pci_pool *pool;
void __iomem *hcr;
struct mutex hcr_mutex;
struct semaphore poll_sem;
struct semaphore event_sem;
int max_cmds;
spinlock_t context_lock;
int free_head;
struct mlx4_cmd_context *context;
u16 token_mask;
u8 use_events;
u8 toggle;
};
struct mlx4_uar_table {
struct mlx4_bitmap bitmap;
};
struct mlx4_mr_table {
struct mlx4_bitmap mpt_bitmap;
struct mlx4_buddy mtt_buddy;
u64 mtt_base;
u64 mpt_base;
struct mlx4_icm_table mtt_table;
struct mlx4_icm_table dmpt_table;
};
struct mlx4_cq_table {
struct mlx4_bitmap bitmap;
spinlock_t lock;
struct radix_tree_root tree;
struct mlx4_icm_table table;
struct mlx4_icm_table cmpt_table;
};
struct mlx4_eq_table {
struct mlx4_bitmap bitmap;
void __iomem *clr_int;
void __iomem *uar_map[(MLX4_NUM_EQ + 6) / 4];
u32 clr_mask;
struct mlx4_eq eq[MLX4_NUM_EQ];
u64 icm_virt;
struct page *icm_page;
dma_addr_t icm_dma;
struct mlx4_icm_table cmpt_table;
int have_irq;
u8 inta_pin;
};
struct mlx4_srq_table {
struct mlx4_bitmap bitmap;
spinlock_t lock;
struct radix_tree_root tree;
struct mlx4_icm_table table;
struct mlx4_icm_table cmpt_table;
};
struct mlx4_qp_table {
struct mlx4_bitmap bitmap;
u32 rdmarc_base;
int rdmarc_shift;
spinlock_t lock;
struct mlx4_icm_table qp_table;
struct mlx4_icm_table auxc_table;
struct mlx4_icm_table altc_table;
struct mlx4_icm_table rdmarc_table;
struct mlx4_icm_table cmpt_table;
};
struct mlx4_mcg_table {
struct mutex mutex;
struct mlx4_bitmap bitmap;
struct mlx4_icm_table table;
};
struct mlx4_catas_err {
u32 __iomem *map;
struct timer_list timer;
struct list_head list;
};
struct mlx4_priv {
struct mlx4_dev dev;
struct list_head dev_list;
struct list_head ctx_list;
spinlock_t ctx_lock;
struct list_head pgdir_list;
struct mutex pgdir_mutex;
struct mlx4_fw fw;
struct mlx4_cmd cmd;
struct mlx4_bitmap pd_bitmap;
struct mlx4_uar_table uar_table;
struct mlx4_mr_table mr_table;
struct mlx4_cq_table cq_table;
struct mlx4_eq_table eq_table;
struct mlx4_srq_table srq_table;
struct mlx4_qp_table qp_table;
struct mlx4_mcg_table mcg_table;
struct mlx4_catas_err catas_err;
void __iomem *clr_base;
struct mlx4_uar driver_uar;
void __iomem *kar;
};
static inline struct mlx4_priv *mlx4_priv(struct mlx4_dev *dev)
{
return container_of(dev, struct mlx4_priv, dev);
}
u32 mlx4_bitmap_alloc(struct mlx4_bitmap *bitmap);
void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj);
u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align);
void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt);
int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, u32 reserved);
void mlx4_bitmap_cleanup(struct mlx4_bitmap *bitmap);
int mlx4_reset(struct mlx4_dev *dev);
int mlx4_init_pd_table(struct mlx4_dev *dev);
int mlx4_init_uar_table(struct mlx4_dev *dev);
int mlx4_init_mr_table(struct mlx4_dev *dev);
int mlx4_init_eq_table(struct mlx4_dev *dev);
int mlx4_init_cq_table(struct mlx4_dev *dev);
int mlx4_init_qp_table(struct mlx4_dev *dev);
int mlx4_init_srq_table(struct mlx4_dev *dev);
int mlx4_init_mcg_table(struct mlx4_dev *dev);
void mlx4_cleanup_pd_table(struct mlx4_dev *dev);
void mlx4_cleanup_uar_table(struct mlx4_dev *dev);
void mlx4_cleanup_mr_table(struct mlx4_dev *dev);
void mlx4_cleanup_eq_table(struct mlx4_dev *dev);
void mlx4_cleanup_cq_table(struct mlx4_dev *dev);
void mlx4_cleanup_qp_table(struct mlx4_dev *dev);
void mlx4_cleanup_srq_table(struct mlx4_dev *dev);
void mlx4_cleanup_mcg_table(struct mlx4_dev *dev);
void mlx4_start_catas_poll(struct mlx4_dev *dev);
void mlx4_stop_catas_poll(struct mlx4_dev *dev);
int mlx4_catas_init(void);
void mlx4_catas_cleanup(void);
int mlx4_restart_one(struct pci_dev *pdev);
int mlx4_register_device(struct mlx4_dev *dev);
void mlx4_unregister_device(struct mlx4_dev *dev);
void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_dev_event type, int port);
struct mlx4_dev_cap;
struct mlx4_init_hca_param;
u64 mlx4_make_profile(struct mlx4_dev *dev,
struct mlx4_profile *request,
struct mlx4_dev_cap *dev_cap,
struct mlx4_init_hca_param *init_hca);
int mlx4_map_eq_icm(struct mlx4_dev *dev, u64 icm_virt);
void mlx4_unmap_eq_icm(struct mlx4_dev *dev);
int mlx4_cmd_init(struct mlx4_dev *dev);
void mlx4_cmd_cleanup(struct mlx4_dev *dev);
void mlx4_cmd_event(struct mlx4_dev *dev, u16 token, u8 status, u64 out_param);
int mlx4_cmd_use_events(struct mlx4_dev *dev);
void mlx4_cmd_use_polling(struct mlx4_dev *dev);
void mlx4_cq_completion(struct mlx4_dev *dev, u32 cqn);
void mlx4_cq_event(struct mlx4_dev *dev, u32 cqn, int event_type);
void mlx4_qp_event(struct mlx4_dev *dev, u32 qpn, int event_type);
void mlx4_srq_event(struct mlx4_dev *dev, u32 srqn, int event_type);
void mlx4_handle_catas_err(struct mlx4_dev *dev);
#endif /* MLX4_H */
|