a1ca21f99026a0dced7268c2b7779fd8591e321c
[people/pcmattman/gpxe.git] / src / drivers / net / mlx_ipoib / arbel.h
1 #ifndef _ARBEL_H
2 #define _ARBEL_H
3
4 /** @file
5  *
6  * Mellanox Arbel Infiniband HCA driver
7  *
8  */
9
10 /*
11  * Hardware constants
12  *
13  */
14
15 /* UAR context table (UCE) resource types */
16 #define ARBEL_UAR_RES_NONE              0x00
17 #define ARBEL_UAR_RES_CQ_CI             0x01
18 #define ARBEL_UAR_RES_CQ_ARM            0x02
19 #define ARBEL_UAR_RES_SQ                0x03
20 #define ARBEL_UAR_RES_RQ                0x04
21 #define ARBEL_UAR_RES_GROUP_SEP         0x07
22
23 /* Work queue entry and completion queue entry opcodes */
24 #define ARBEL_OPCODE_SEND               0x0a
25 #define ARBEL_OPCODE_RECV_ERROR         0xfe
26 #define ARBEL_OPCODE_SEND_ERROR         0xff
27
28 /* HCA command register opcodes */
29 #define ARBEL_HCR_QUERY_DEV_LIM         0x0003
30 #define ARBEL_HCR_SW2HW_CQ              0x0016
31 #define ARBEL_HCR_HW2SW_CQ              0x0017
32
33 /*
34  * Wrapper structures for hardware datatypes
35  *
36  */
37
38 struct MLX_DECLARE_STRUCT ( arbelprm_completion_queue_context );
39 struct MLX_DECLARE_STRUCT ( arbelprm_completion_queue_entry );
40 struct MLX_DECLARE_STRUCT ( arbelprm_completion_with_error );
41 struct MLX_DECLARE_STRUCT ( arbelprm_cq_arm_db_record );
42 struct MLX_DECLARE_STRUCT ( arbelprm_cq_ci_db_record );
43 struct MLX_DECLARE_STRUCT ( arbelprm_hca_command_register );
44 struct MLX_DECLARE_STRUCT ( arbelprm_qp_db_record );
45 struct MLX_DECLARE_STRUCT ( arbelprm_query_dev_lim );
46 struct MLX_DECLARE_STRUCT ( arbelprm_recv_wqe_segment_next );
47 struct MLX_DECLARE_STRUCT ( arbelprm_send_doorbell );
48 struct MLX_DECLARE_STRUCT ( arbelprm_ud_address_vector );
49 struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_ctrl_send );
50 struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_data_ptr );
51 struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_next );
52 struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_ud );
53
54 /*
55  * Composite hardware datatypes
56  *
57  */
58
59 #define ARBEL_MAX_GATHER 1
60
61 struct arbelprm_ud_send_wqe {
62         struct arbelprm_wqe_segment_next next;
63         struct arbelprm_wqe_segment_ctrl_send ctrl;
64         struct arbelprm_wqe_segment_ud ud;
65         struct arbelprm_wqe_segment_data_ptr data[ARBEL_MAX_GATHER];
66 } __attribute__ (( packed ));
67
68 #define ARBEL_MAX_SCATTER 1
69
70 struct arbelprm_recv_wqe {
71         /* The autogenerated header is inconsistent between send and
72          * receive WQEs.  The "ctrl" structure for receive WQEs is
73          * defined to include the "next" structure.  Since the "ctrl"
74          * part of the "ctrl" structure contains only "reserved, must
75          * be zero" bits, we ignore its definition and provide
76          * something more usable.
77          */
78         struct arbelprm_recv_wqe_segment_next next;
79         uint32_t ctrl[2]; /* All "reserved, must be zero" */
80         struct arbelprm_wqe_segment_data_ptr data[ARBEL_MAX_SCATTER];
81 } __attribute__ (( packed ));
82
83 union arbelprm_completion_entry {
84         struct arbelprm_completion_queue_entry normal;
85         struct arbelprm_completion_with_error error;
86 } __attribute__ (( packed ));
87
88 union arbelprm_doorbell_record {
89         struct arbelprm_cq_arm_db_record cq_arm;
90         struct arbelprm_cq_ci_db_record cq_ci;
91         struct arbelprm_qp_db_record qp;
92 } __attribute__ (( packed ));
93
94 union arbelprm_doorbell_register {
95         struct arbelprm_send_doorbell send;
96         uint32_t dword[2];
97 } __attribute__ (( packed ));
98
99 /*
100  * gPXE-specific definitions
101  *
102  */
103
104 /** Arbel device limits */
105 struct arbel_dev_limits {
106         /** Number of reserver UARs */
107         unsigned long reserved_uars;
108         /** Number of reserved CQs */
109         unsigned long reserved_cqs;
110         /** Number of reserved QPs */
111         unsigned long reserved_qps;
112 };
113
114 /** Alignment of Arbel send work queue entries */
115 #define ARBEL_SEND_WQE_ALIGN 128
116
117 /** An Arbel send work queue entry */
118 union arbel_send_wqe {
119         struct arbelprm_ud_send_wqe ud;
120         uint8_t force_align[ARBEL_SEND_WQE_ALIGN];
121 } __attribute__ (( packed ));
122
123 /** An Arbel send work queue */
124 struct arbel_send_work_queue {
125         /** Doorbell record number */
126         unsigned int doorbell_idx;
127         /** Work queue entries */
128         union arbel_send_wqe *wqe;
129 };
130
131 /** Alignment of Arbel receive work queue entries */
132 #define ARBEL_RECV_WQE_ALIGN 64
133
134 /** An Arbel receive work queue entry */
135 union arbel_recv_wqe {
136         struct arbelprm_recv_wqe recv;
137         uint8_t force_align[ARBEL_RECV_WQE_ALIGN];
138 } __attribute__ (( packed ));
139
140 /** An Arbel receive work queue */
141 struct arbel_recv_work_queue {
142         /** Doorbell record number */
143         unsigned int doorbell_idx;
144         /** Work queue entries */
145         union arbel_recv_wqe *wqe;
146 };
147
148 /** Maximum number of allocatable queue pairs
149  *
150  * This is a policy decision, not a device limit.
151  */
152 #define ARBEL_MAX_QPS           8
153
154 /** Base queue pair number */
155 #define ARBEL_QPN_BASE 0x550000
156
157 /** An Arbel queue pair */
158 struct arbel_queue_pair {
159         /** Infiniband queue pair */
160         struct ib_queue_pair qp;
161         /** Send work queue */
162         struct arbel_send_work_queue send;
163         /** Receive work queue */
164         struct arbel_recv_work_queue recv;
165 };
166
167 /** Maximum number of allocatable completion queues
168  *
169  * This is a policy decision, not a device limit.
170  */
171 #define ARBEL_MAX_CQS           8
172
173 /** An Arbel completion queue */
174 struct arbel_completion_queue {
175         /** Consumer counter doorbell record number */
176         unsigned int ci_doorbell_idx;
177         /** Arm queue doorbell record number */
178         unsigned int arm_doorbell_idx;
179         /** Completion queue entries */
180         union arbelprm_completion_entry *cqe;
181 };
182
183 /** An Arbel resource bitmask */
184 typedef uint32_t arbel_bitmask_t;
185
186 /** Size of an Arbel resource bitmask */
187 #define ARBEL_BITMASK_SIZE(max_entries)                                      \
188         ( ( (max_entries) + ( 8 * sizeof ( arbel_bitmask_t ) ) - 1 ) /       \
189           ( 8 * sizeof ( arbel_bitmask_t ) ) )
190
191 /** An Arbel device */
192 struct arbel {
193         /** Configuration registers */
194         void *config;
195         /** Command input mailbox */
196         void *mailbox_in;
197         /** Command output mailbox */
198         void *mailbox_out;
199
200         /** User Access Region */
201         void *uar;
202         /** Doorbell records */
203         union arbelprm_doorbell_record *db_rec;
204         /** Reserved LKey
205          *
206          * Used to get unrestricted memory access.
207          */
208         unsigned long reserved_lkey;
209         /** Event queue number */
210         unsigned long eqn;
211
212         /** Completion queue in-use bitmask */
213         arbel_bitmask_t cq_inuse[ ARBEL_BITMASK_SIZE ( ARBEL_MAX_CQS ) ];
214         /** Queue pair in-use bitmask */
215         arbel_bitmask_t qp_inuse[ ARBEL_BITMASK_SIZE ( ARBEL_MAX_QPS ) ];
216         
217         /** Device limits */
218         struct arbel_dev_limits limits;
219 };
220
221 /** Global protection domain */
222 #define ARBEL_GLOBAL_PD                 0x123456
223
224 /*
225  * HCA commands
226  *
227  */
228
229 #define ARBEL_HCR_BASE                  0x80680
230 #define ARBEL_HCR_REG(x)                ( ARBEL_HCR_BASE + 4 * (x) )
231 #define ARBEL_HCR_MAX_WAIT_MS           2000
232
233 /* HCA command is split into
234  *
235  * bits  11:0   Opcode
236  * bit     12   Input uses mailbox
237  * bit     13   Output uses mailbox
238  * bits 22:14   Input parameter length (in dwords)
239  * bits 31:23   Output parameter length (in dwords)
240  *
241  * Encoding the information in this way allows us to cut out several
242  * parameters to the arbel_command() call.
243  */
244 #define ARBEL_HCR_IN_MBOX               0x00001000UL
245 #define ARBEL_HCR_OUT_MBOX              0x00002000UL
246 #define ARBEL_HCR_OPCODE( _command )    ( (_command) & 0xfff )
247 #define ARBEL_HCR_IN_LEN( _command )    ( ( (_command) >> 12 ) & 0x7fc )
248 #define ARBEL_HCR_OUT_LEN( _command )   ( ( (_command) >> 21 ) & 0x7fc )
249
250 /** Build HCR command from component parts */
251 #define ARBEL_HCR_CMD( _opcode, _in_mbox, _in_len, _out_mbox, _out_len )     \
252         ( (_opcode) |                                                        \
253           ( (_in_mbox) ? ARBEL_HCR_IN_MBOX : 0 ) |                           \
254           ( ( (_in_len) / 4 ) << 14 ) |                                      \
255           ( (_out_mbox) ? ARBEL_HCR_OUT_MBOX : 0 ) |                         \
256           ( ( (_out_len) / 4 ) << 23 ) )
257
258 #define ARBEL_HCR_IN_CMD( _opcode, _in_mbox, _in_len )                       \
259         ARBEL_HCR_CMD ( _opcode, _in_mbox, _in_len, 0, 0 )
260
261 #define ARBEL_HCR_OUT_CMD( _opcode, _out_mbox, _out_len )                    \
262         ARBEL_HCR_CMD ( _opcode, 0, 0, _out_mbox, _out_len )
263
264 #define ARBEL_HCR_VOID_CMD( _opcode )                                        \
265         ARBEL_HCR_CMD ( _opcode, 0, 0, 0, 0 )
266
267 /*
268  * Doorbell record allocation
269  *
270  * The doorbell record map looks like:
271  *
272  *    ARBEL_MAX_CQS * Arm completion queue doorbell
273  *    ARBEL_MAX_QPS * Send work request doorbell
274  *    Group separator
275  *    ...(empty space)...
276  *    ARBEL_MAX_QPS * Receive work request doorbell
277  *    ARBEL_MAX_CQS * Completion queue consumer counter update doorbell
278  */
279
280 #define ARBEL_MAX_DOORBELL_RECORDS 512
281 #define ARBEL_GROUP_SEPARATOR_DOORBELL ( ARBEL_MAX_CQS + ARBEL_MAX_QPS )
282
283 /**
284  * Get arm completion queue doorbell index
285  *
286  * @v cqn_offset        Completion queue number offset
287  * @ret doorbell_idx    Doorbell index
288  */
289 static inline unsigned int
290 arbel_cq_arm_doorbell_idx ( unsigned int cqn_offset ) {
291         return cqn_offset;
292 }
293
294 /**
295  * Get send work request doorbell index
296  *
297  * @v qpn_offset        Queue pair number offset
298  * @ret doorbell_idx    Doorbell index
299  */
300 static inline unsigned int
301 arbel_send_doorbell_idx ( unsigned int qpn_offset ) {
302         return ( ARBEL_MAX_CQS + qpn_offset );
303 }
304
305 /**
306  * Get receive work request doorbell index
307  *
308  * @v qpn_offset        Queue pair number offset
309  * @ret doorbell_idx    Doorbell index
310  */
311 static inline unsigned int
312 arbel_recv_doorbell_idx ( unsigned int qpn_offset ) {
313         return ( ARBEL_MAX_DOORBELL_RECORDS - ARBEL_MAX_CQS - qpn_offset - 1 );
314 }
315
316 /**
317  * Get completion queue consumer counter doorbell index
318  *
319  * @v cqn_offset        Completion queue number offset
320  * @ret doorbell_idx    Doorbell index
321  */
322 static inline unsigned int
323 arbel_cq_ci_doorbell_idx ( unsigned int cqn_offset ) {
324         return ( ARBEL_MAX_DOORBELL_RECORDS - cqn_offset - 1 );
325 }
326
327 #endif /* _ARBEL_H */