1 #ifndef _ARBEL_H
2 #define _ARBEL_H
3 
4 /** @file
5  *
6  * Mellanox Arbel Infiniband HCA driver
7  *
8  */
9 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 
12 #include <stdint.h>
13 #include <ipxe/uaccess.h>
14 #include <ipxe/ib_packet.h>
15 #include "mlx_bitops.h"
16 #include "MT25218_PRM.h"
17 
18 /*
19  * Hardware constants
20  *
21  */
22 
23 /* Ports in existence */
24 #define ARBEL_NUM_PORTS			2
25 #define ARBEL_PORT_BASE			1
26 
27 /* PCI BARs */
28 #define ARBEL_PCI_CONFIG_BAR		PCI_BASE_ADDRESS_0
29 #define ARBEL_PCI_CONFIG_BAR_SIZE	0x100000
30 #define ARBEL_PCI_UAR_BAR		PCI_BASE_ADDRESS_2
31 #define ARBEL_PCI_UAR_IDX		1
32 #define ARBEL_PCI_UAR_SIZE		0x1000
33 
34 /* Device reset */
35 #define ARBEL_RESET_OFFSET		0x0f0010
36 #define ARBEL_RESET_MAGIC		0x01000000UL
37 #define ARBEL_RESET_WAIT_TIME_MS	1000
38 
39 /* UAR context table (UCE) resource types */
40 #define ARBEL_UAR_RES_NONE		0x00
41 #define ARBEL_UAR_RES_CQ_CI		0x01
42 #define ARBEL_UAR_RES_CQ_ARM		0x02
43 #define ARBEL_UAR_RES_SQ		0x03
44 #define ARBEL_UAR_RES_RQ		0x04
45 #define ARBEL_UAR_RES_GROUP_SEP		0x07
46 
47 /* Work queue entry and completion queue entry opcodes */
48 #define ARBEL_OPCODE_SEND		0x0a
49 #define ARBEL_OPCODE_RECV_ERROR		0xfe
50 #define ARBEL_OPCODE_SEND_ERROR		0xff
51 
52 /* HCA command register opcodes */
53 #define ARBEL_HCR_QUERY_DEV_LIM		0x0003
54 #define ARBEL_HCR_QUERY_FW		0x0004
55 #define ARBEL_HCR_INIT_HCA		0x0007
56 #define ARBEL_HCR_CLOSE_HCA		0x0008
57 #define ARBEL_HCR_INIT_IB		0x0009
58 #define ARBEL_HCR_CLOSE_IB		0x000a
59 #define ARBEL_HCR_SW2HW_MPT		0x000d
60 #define ARBEL_HCR_MAP_EQ		0x0012
61 #define ARBEL_HCR_SW2HW_EQ		0x0013
62 #define ARBEL_HCR_HW2SW_EQ		0x0014
63 #define ARBEL_HCR_SW2HW_CQ		0x0016
64 #define ARBEL_HCR_HW2SW_CQ		0x0017
65 #define ARBEL_HCR_QUERY_CQ		0x0018
66 #define ARBEL_HCR_RST2INIT_QPEE		0x0019
67 #define ARBEL_HCR_INIT2RTR_QPEE		0x001a
68 #define ARBEL_HCR_RTR2RTS_QPEE		0x001b
69 #define ARBEL_HCR_RTS2RTS_QPEE		0x001c
70 #define ARBEL_HCR_2RST_QPEE		0x0021
71 #define ARBEL_HCR_QUERY_QPEE		0x0022
72 #define ARBEL_HCR_CONF_SPECIAL_QP	0x0023
73 #define ARBEL_HCR_MAD_IFC		0x0024
74 #define ARBEL_HCR_READ_MGM		0x0025
75 #define ARBEL_HCR_WRITE_MGM		0x0026
76 #define ARBEL_HCR_MGID_HASH		0x0027
77 #define ARBEL_HCR_RUN_FW		0x0ff6
78 #define ARBEL_HCR_DISABLE_LAM		0x0ff7
79 #define ARBEL_HCR_ENABLE_LAM		0x0ff8
80 #define ARBEL_HCR_UNMAP_ICM		0x0ff9
81 #define ARBEL_HCR_MAP_ICM		0x0ffa
82 #define ARBEL_HCR_UNMAP_ICM_AUX		0x0ffb
83 #define ARBEL_HCR_MAP_ICM_AUX		0x0ffc
84 #define ARBEL_HCR_SET_ICM_SIZE		0x0ffd
85 #define ARBEL_HCR_UNMAP_FA		0x0ffe
86 #define ARBEL_HCR_MAP_FA		0x0fff
87 
88 /* Service types */
89 #define ARBEL_ST_RC			0x00
90 #define ARBEL_ST_UD			0x03
91 #define ARBEL_ST_MLX			0x07
92 
93 /* MTUs */
94 #define ARBEL_MTU_2048			0x04
95 
96 #define ARBEL_NO_EQ			64
97 
98 #define ARBEL_INVALID_LKEY		0x00000100UL
99 
100 #define ARBEL_PAGE_SIZE			( ( size_t ) 4096 )
101 
102 #define ARBEL_RDB_ENTRY_SIZE		( ( size_t ) 32 )
103 
104 #define ARBEL_DB_POST_SND_OFFSET	0x10
105 #define ARBEL_DB_EQ_OFFSET(_eqn)	( 0x08 * (_eqn) )
106 
107 #define ARBEL_QPEE_OPT_PARAM_QKEY	0x00000020UL
108 
109 #define ARBEL_MAP_EQ			( 0UL << 31 )
110 #define ARBEL_UNMAP_EQ			( 1UL << 31 )
111 
112 #define ARBEL_EV_PORT_STATE_CHANGE	0x09
113 
114 #define ARBEL_LOG_MULTICAST_HASH_SIZE	3
115 
116 #define ARBEL_PM_STATE_ARMED		0x00
117 #define ARBEL_PM_STATE_REARM		0x01
118 #define ARBEL_PM_STATE_MIGRATED		0x03
119 
120 #define ARBEL_RETRY_MAX			0x07
121 
122 /*
123  * Datatypes that seem to be missing from the autogenerated documentation
124  *
125  */
126 struct arbelprm_mgm_hash_st {
127 	pseudo_bit_t reserved0[0x00020];
128 /* -------------- */
129 	pseudo_bit_t hash[0x00010];
130 	pseudo_bit_t reserved1[0x00010];
131 } __attribute__ (( packed ));
132 
133 struct arbelprm_scalar_parameter_st {
134 	pseudo_bit_t reserved0[0x00020];
135 /* -------------- */
136 	pseudo_bit_t value[0x00020];
137 } __attribute__ (( packed ));
138 
139 struct arbelprm_event_mask_st {
140 	pseudo_bit_t reserved0[0x00020];
141 /* -------------- */
142 	pseudo_bit_t completion[0x00001];
143 	pseudo_bit_t path_migration_succeeded[0x00001];
144 	pseudo_bit_t communication_established[0x00001];
145 	pseudo_bit_t send_queue_drained[0x00001];
146 	pseudo_bit_t cq_error[0x00001];
147 	pseudo_bit_t wq_catastrophe[0x00001];
148 	pseudo_bit_t qpc_catastrophe[0x00001];
149 	pseudo_bit_t path_migration_failed[0x00001];
150 	pseudo_bit_t reserved1[0x00001];
151 	pseudo_bit_t port_state_change[0x00001];
152 	pseudo_bit_t command_done[0x00001];
153 	pseudo_bit_t reserved2[0x00005];
154 	pseudo_bit_t wq_invalid_request[0x00001];
155 	pseudo_bit_t wq_access_violation[0x00001];
156 	pseudo_bit_t srq_catastrophe[0x00001];
157 	pseudo_bit_t srq_last_wqe[0x00001];
158 	pseudo_bit_t srq_rq_limit[0x00001];
159 	pseudo_bit_t gpio[0x00001];
160 	pseudo_bit_t clientreregister[0x00001];
161 	pseudo_bit_t path_migration_armed[0x00001];
162 	pseudo_bit_t reserved3[0x00008];
163 } __attribute__ (( packed ));
164 
165 struct arbelprm_eq_set_ci_st {
166 	pseudo_bit_t ci[0x00020];
167 } __attribute__ (( packed ));
168 
169 struct arbelprm_port_state_change_event_st {
170 	pseudo_bit_t reserved[0x00020];
171 	struct arbelprm_port_state_change_st data;
172 } __attribute__ (( packed ));
173 
174 /*
175  * Wrapper structures for hardware datatypes
176  *
177  */
178 
179 struct MLX_DECLARE_STRUCT ( arbelprm_access_lam );
180 struct MLX_DECLARE_STRUCT ( arbelprm_completion_queue_context );
181 struct MLX_DECLARE_STRUCT ( arbelprm_completion_queue_entry );
182 struct MLX_DECLARE_STRUCT ( arbelprm_completion_with_error );
183 struct MLX_DECLARE_STRUCT ( arbelprm_cq_arm_db_record );
184 struct MLX_DECLARE_STRUCT ( arbelprm_cq_ci_db_record );
185 struct MLX_DECLARE_STRUCT ( arbelprm_event_mask );
186 struct MLX_DECLARE_STRUCT ( arbelprm_event_queue_entry );
187 struct MLX_DECLARE_STRUCT ( arbelprm_eq_set_ci );
188 struct MLX_DECLARE_STRUCT ( arbelprm_eqc );
189 struct MLX_DECLARE_STRUCT ( arbelprm_hca_command_register );
190 struct MLX_DECLARE_STRUCT ( arbelprm_init_hca );
191 struct MLX_DECLARE_STRUCT ( arbelprm_init_ib );
192 struct MLX_DECLARE_STRUCT ( arbelprm_mad_ifc );
193 struct MLX_DECLARE_STRUCT ( arbelprm_mgm_entry );
194 struct MLX_DECLARE_STRUCT ( arbelprm_mgm_hash );
195 struct MLX_DECLARE_STRUCT ( arbelprm_mpt );
196 struct MLX_DECLARE_STRUCT ( arbelprm_port_state_change_event );
197 struct MLX_DECLARE_STRUCT ( arbelprm_qp_db_record );
198 struct MLX_DECLARE_STRUCT ( arbelprm_qp_ee_state_transitions );
199 struct MLX_DECLARE_STRUCT ( arbelprm_query_dev_lim );
200 struct MLX_DECLARE_STRUCT ( arbelprm_query_fw );
201 struct MLX_DECLARE_STRUCT ( arbelprm_queue_pair_ee_context_entry );
202 struct MLX_DECLARE_STRUCT ( arbelprm_recv_wqe_segment_next );
203 struct MLX_DECLARE_STRUCT ( arbelprm_scalar_parameter );
204 struct MLX_DECLARE_STRUCT ( arbelprm_send_doorbell );
205 struct MLX_DECLARE_STRUCT ( arbelprm_ud_address_vector );
206 struct MLX_DECLARE_STRUCT ( arbelprm_virtual_physical_mapping );
207 struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_ctrl_mlx );
208 struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_ctrl_send );
209 struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_data_ptr );
210 struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_next );
211 struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_ud );
212 
213 /*
214  * Composite hardware datatypes
215  *
216  */
217 
218 #define ARBEL_MAX_GATHER 2
219 
220 struct arbelprm_ud_send_wqe {
221 	struct arbelprm_wqe_segment_next next;
222 	struct arbelprm_wqe_segment_ctrl_send ctrl;
223 	struct arbelprm_wqe_segment_ud ud;
224 	struct arbelprm_wqe_segment_data_ptr data[ARBEL_MAX_GATHER];
225 } __attribute__ (( packed ));
226 
227 struct arbelprm_mlx_send_wqe {
228 	struct arbelprm_wqe_segment_next next;
229 	struct arbelprm_wqe_segment_ctrl_mlx ctrl;
230 	struct arbelprm_wqe_segment_data_ptr data[ARBEL_MAX_GATHER];
231 	uint8_t headers[IB_MAX_HEADER_SIZE];
232 } __attribute__ (( packed ));
233 
234 struct arbelprm_rc_send_wqe {
235 	struct arbelprm_wqe_segment_next next;
236 	struct arbelprm_wqe_segment_ctrl_send ctrl;
237 	struct arbelprm_wqe_segment_data_ptr data[ARBEL_MAX_GATHER];
238 } __attribute__ (( packed ));
239 
240 #define ARBEL_MAX_SCATTER 2
241 
242 struct arbelprm_recv_wqe {
243 	/* The autogenerated header is inconsistent between send and
244 	 * receive WQEs.  The "ctrl" structure for receive WQEs is
245 	 * defined to include the "next" structure.  Since the "ctrl"
246 	 * part of the "ctrl" structure contains only "reserved, must
247 	 * be zero" bits, we ignore its definition and provide
248 	 * something more usable.
249 	 */
250 	struct arbelprm_recv_wqe_segment_next next;
251 	uint32_t ctrl[2]; /* All "reserved, must be zero" */
252 	struct arbelprm_wqe_segment_data_ptr data[ARBEL_MAX_SCATTER];
253 } __attribute__ (( packed ));
254 
255 union arbelprm_completion_entry {
256 	struct arbelprm_completion_queue_entry normal;
257 	struct arbelprm_completion_with_error error;
258 } __attribute__ (( packed ));
259 
260 union arbelprm_event_entry {
261 	struct arbelprm_event_queue_entry generic;
262 	struct arbelprm_port_state_change_event port_state_change;
263 } __attribute__ (( packed ));
264 
265 union arbelprm_doorbell_record {
266 	struct arbelprm_cq_arm_db_record cq_arm;
267 	struct arbelprm_cq_ci_db_record cq_ci;
268 	struct arbelprm_qp_db_record qp;
269 } __attribute__ (( packed ));
270 
271 union arbelprm_doorbell_register {
272 	struct arbelprm_send_doorbell send;
273 	uint32_t dword[2];
274 } __attribute__ (( packed ));
275 
276 union arbelprm_eq_doorbell_register {
277 	struct arbelprm_eq_set_ci ci;
278 	uint32_t dword[1];
279 } __attribute__ (( packed ));
280 
281 union arbelprm_mad {
282 	struct arbelprm_mad_ifc ifc;
283 	union ib_mad mad;
284 } __attribute__ (( packed ));
285 
286 /*
287  * iPXE-specific definitions
288  *
289  */
290 
291 /** Arbel device limits */
292 struct arbel_dev_limits {
293 	/** Number of reserved QPs */
294 	unsigned int reserved_qps;
295 	/** QP context entry size */
296 	size_t qpc_entry_size;
297 	/** Extended QP context entry size */
298 	size_t eqpc_entry_size;
299 	/** Number of reserved SRQs */
300 	unsigned int reserved_srqs;
301 	/** SRQ context entry size */
302 	size_t srqc_entry_size;
303 	/** Number of reserved EEs */
304 	unsigned int reserved_ees;
305 	/** EE context entry size */
306 	size_t eec_entry_size;
307 	/** Extended EE context entry size */
308 	size_t eeec_entry_size;
309 	/** Number of reserved CQs */
310 	unsigned int reserved_cqs;
311 	/** CQ context entry size */
312 	size_t cqc_entry_size;
313 	/** Number of reserved EQs */
314 	unsigned int reserved_eqs;
315 	/** Number of reserved MTTs */
316 	unsigned int reserved_mtts;
317 	/** MTT entry size */
318 	size_t mtt_entry_size;
319 	/** Number of reserved MRWs */
320 	unsigned int reserved_mrws;
321 	/** MPT entry size */
322 	size_t mpt_entry_size;
323 	/** Number of reserved RDBs */
324 	unsigned int reserved_rdbs;
325 	/** EQ context entry size */
326 	size_t eqc_entry_size;
327 	/** Number of reserved UARs */
328 	unsigned int reserved_uars;
329 	/** UAR scratchpad entry size */
330 	size_t uar_scratch_entry_size;
331 };
332 
333 /** Alignment of Arbel send work queue entries */
334 #define ARBEL_SEND_WQE_ALIGN 128
335 
336 /** An Arbel send work queue entry */
337 union arbel_send_wqe {
338 	struct arbelprm_wqe_segment_next next;
339 	struct arbelprm_ud_send_wqe ud;
340 	struct arbelprm_mlx_send_wqe mlx;
341 	struct arbelprm_rc_send_wqe rc;
342 	uint8_t force_align[ARBEL_SEND_WQE_ALIGN];
343 } __attribute__ (( packed ));
344 
345 /** An Arbel send work queue */
346 struct arbel_send_work_queue {
347 	/** Doorbell record number */
348 	unsigned int doorbell_idx;
349 	/** Work queue entries */
350 	union arbel_send_wqe *wqe;
351 	/** Size of work queue */
352 	size_t wqe_size;
353 };
354 
355 /** Alignment of Arbel receive work queue entries */
356 #define ARBEL_RECV_WQE_ALIGN 64
357 
358 /** An Arbel receive work queue entry */
359 union arbel_recv_wqe {
360 	struct arbelprm_recv_wqe recv;
361 	uint8_t force_align[ARBEL_RECV_WQE_ALIGN];
362 } __attribute__ (( packed ));
363 
364 /** An Arbel receive work queue */
365 struct arbel_recv_work_queue {
366 	/** Doorbell record number */
367 	unsigned int doorbell_idx;
368 	/** Work queue entries */
369 	union arbel_recv_wqe *wqe;
370 	/** Size of work queue */
371 	size_t wqe_size;
372 	/** GRH buffers (if applicable) */
373 	struct ib_global_route_header *grh;
374 	/** Size of GRB buffers */
375 	size_t grh_size;
376 };
377 
378 /** Number of special queue pairs */
379 #define ARBEL_NUM_SPECIAL_QPS 4
380 
381 /** Number of queue pairs reserved for the "special QP" block
382  *
383  * The special QPs must be in (2n,2n+1) pairs, hence we need to
384  * reserve one extra QP to allow for alignment.
385  */
386 #define ARBEL_RSVD_SPECIAL_QPS	( ARBEL_NUM_SPECIAL_QPS + 1 )
387 
388 /** Maximum number of allocatable queue pairs
389  *
390  * This is a policy decision, not a device limit.
391  */
392 #define ARBEL_MAX_QPS		8
393 
394 /** Queue pair number randomisation mask */
395 #define ARBEL_QPN_RANDOM_MASK 0xfff000
396 
397 /** Arbel queue pair state */
398 enum arbel_queue_pair_state {
399 	ARBEL_QP_ST_RST = 0,
400 	ARBEL_QP_ST_INIT,
401 	ARBEL_QP_ST_RTR,
402 	ARBEL_QP_ST_RTS,
403 };
404 
405 /** An Arbel queue pair */
406 struct arbel_queue_pair {
407 	/** Send work queue */
408 	struct arbel_send_work_queue send;
409 	/** Receive work queue */
410 	struct arbel_recv_work_queue recv;
411 	/** Queue state */
412 	enum arbel_queue_pair_state state;
413 };
414 
415 /** Maximum number of allocatable completion queues
416  *
417  * This is a policy decision, not a device limit.
418  */
419 #define ARBEL_MAX_CQS		8
420 
421 /** An Arbel completion queue */
422 struct arbel_completion_queue {
423 	/** Consumer counter doorbell record number */
424 	unsigned int ci_doorbell_idx;
425 	/** Arm queue doorbell record number */
426 	unsigned int arm_doorbell_idx;
427 	/** Completion queue entries */
428 	union arbelprm_completion_entry *cqe;
429 	/** Size of completion queue */
430 	size_t cqe_size;
431 };
432 
433 /** Maximum number of allocatable event queues
434  *
435  * This is a policy decision, not a device limit.
436  */
437 #define ARBEL_MAX_EQS		64
438 
439 /** A Arbel event queue */
440 struct arbel_event_queue {
441 	/** Event queue entries */
442 	union arbelprm_event_entry *eqe;
443 	/** Size of event queue */
444 	size_t eqe_size;
445 	/** Event queue number */
446 	unsigned long eqn;
447 	/** Next event queue entry index */
448 	unsigned long next_idx;
449 	/** Doorbell register */
450 	void *doorbell;
451 };
452 
453 /** Number of event queue entries
454  *
455  * This is a policy decision.
456  */
457 #define ARBEL_NUM_EQES		4
458 
459 
460 /** An Arbel resource bitmask */
461 typedef uint32_t arbel_bitmask_t;
462 
463 /** Size of an Arbel resource bitmask */
464 #define ARBEL_BITMASK_SIZE(max_entries)					     \
465 	( ( (max_entries) + ( 8 * sizeof ( arbel_bitmask_t ) ) - 1 ) /	     \
466 	  ( 8 * sizeof ( arbel_bitmask_t ) ) )
467 
468 /** An Arbel device */
469 struct arbel {
470 	/** PCI device */
471 	struct pci_device *pci;
472 	/** PCI configuration registers */
473 	void *config;
474 	/** PCI user Access Region */
475 	void *uar;
476 	/** Event queue consumer index doorbells */
477 	void *eq_ci_doorbells;
478 
479 	/** Command input mailbox */
480 	void *mailbox_in;
481 	/** Command output mailbox */
482 	void *mailbox_out;
483 
484 	/** Device open request counter */
485 	unsigned int open_count;
486 
487 	/** Firmware size */
488 	size_t firmware_len;
489 	/** Firmware area in external memory
490 	 *
491 	 * This is allocated when first needed, and freed only on
492 	 * final teardown, in order to avoid memory map changes at
493 	 * runtime.
494 	 */
495 	userptr_t firmware_area;
496 	/** ICM size */
497 	size_t icm_len;
498 	/** ICM AUX size */
499 	size_t icm_aux_len;
500 	/** ICM area
501 	 *
502 	 * This is allocated when first needed, and freed only on
503 	 * final teardown, in order to avoid memory map changes at
504 	 * runtime.
505 	 */
506 	userptr_t icm;
507 	/** Offset within ICM of doorbell records */
508 	size_t db_rec_offset;
509 	/** Doorbell records */
510 	union arbelprm_doorbell_record *db_rec;
511 	/** Event queue */
512 	struct arbel_event_queue eq;
513 	/** Unrestricted LKey
514 	 *
515 	 * Used to get unrestricted memory access.
516 	 */
517 	unsigned long lkey;
518 
519 	/** Completion queue in-use bitmask */
520 	arbel_bitmask_t cq_inuse[ ARBEL_BITMASK_SIZE ( ARBEL_MAX_CQS ) ];
521 	/** Queue pair in-use bitmask */
522 	arbel_bitmask_t qp_inuse[ ARBEL_BITMASK_SIZE ( ARBEL_MAX_QPS ) ];
523 
524 	/** Device limits */
525 	struct arbel_dev_limits limits;
526 	/** Special QPN base */
527 	unsigned long special_qpn_base;
528 	/** QPN base */
529 	unsigned long qpn_base;
530 
531 	/** Infiniband devices */
532 	struct ib_device *ibdev[ARBEL_NUM_PORTS];
533 };
534 
535 /** Global protection domain */
536 #define ARBEL_GLOBAL_PD			0x123456
537 
538 /** Memory key prefix */
539 #define ARBEL_MKEY_PREFIX		0x77000000UL
540 
541 /*
542  * HCA commands
543  *
544  */
545 
546 #define ARBEL_HCR_BASE			0x80680
547 #define ARBEL_HCR_REG(x)		( ARBEL_HCR_BASE + 4 * (x) )
548 #define ARBEL_HCR_MAX_WAIT_MS		2000
549 #define ARBEL_MBOX_ALIGN		4096
550 #define ARBEL_MBOX_SIZE			512
551 
552 /* HCA command is split into
553  *
554  * bits  11:0	Opcode
555  * bit     12	Input uses mailbox
556  * bit     13	Output uses mailbox
557  * bits 22:14	Input parameter length (in dwords)
558  * bits 31:23	Output parameter length (in dwords)
559  *
560  * Encoding the information in this way allows us to cut out several
561  * parameters to the arbel_command() call.
562  */
563 #define ARBEL_HCR_IN_MBOX		0x00001000UL
564 #define ARBEL_HCR_OUT_MBOX		0x00002000UL
565 #define ARBEL_HCR_OPCODE( _command )	( (_command) & 0xfff )
566 #define ARBEL_HCR_IN_LEN( _command )	( ( (_command) >> 12 ) & 0x7fc )
567 #define ARBEL_HCR_OUT_LEN( _command )	( ( (_command) >> 21 ) & 0x7fc )
568 
569 /** Build HCR command from component parts */
570 #define ARBEL_HCR_INOUT_CMD( _opcode, _in_mbox, _in_len,		     \
571 			     _out_mbox, _out_len )			     \
572 	( (_opcode) |							     \
573 	  ( (_in_mbox) ? ARBEL_HCR_IN_MBOX : 0 ) |			     \
574 	  ( ( (_in_len) / 4 ) << 14 ) |					     \
575 	  ( (_out_mbox) ? ARBEL_HCR_OUT_MBOX : 0 ) |			     \
576 	  ( ( (_out_len) / 4 ) << 23 ) )
577 
578 #define ARBEL_HCR_IN_CMD( _opcode, _in_mbox, _in_len )			     \
579 	ARBEL_HCR_INOUT_CMD ( _opcode, _in_mbox, _in_len, 0, 0 )
580 
581 #define ARBEL_HCR_OUT_CMD( _opcode, _out_mbox, _out_len )		     \
582 	ARBEL_HCR_INOUT_CMD ( _opcode, 0, 0, _out_mbox, _out_len )
583 
584 #define ARBEL_HCR_VOID_CMD( _opcode )					     \
585 	ARBEL_HCR_INOUT_CMD ( _opcode, 0, 0, 0, 0 )
586 
587 /*
588  * Doorbell record allocation
589  *
590  * The doorbell record map looks like:
591  *
592  *    ARBEL_MAX_CQS * Arm completion queue doorbell
593  *    ARBEL_MAX_QPS * Send work request doorbell
594  *    Group separator
595  *    ...(empty space)...
596  *    ARBEL_MAX_QPS * Receive work request doorbell
597  *    ARBEL_MAX_CQS * Completion queue consumer counter update doorbell
598  */
599 
600 #define ARBEL_MAX_DOORBELL_RECORDS 512
601 #define ARBEL_GROUP_SEPARATOR_DOORBELL \
602 	( ARBEL_MAX_CQS + ARBEL_RSVD_SPECIAL_QPS + ARBEL_MAX_QPS )
603 
604 /**
605  * Get arm completion queue doorbell index
606  *
607  * @v arbel		Arbel device
608  * @v cq		Completion queue
609  * @ret doorbell_idx	Doorbell index
610  */
611 static inline unsigned int
arbel_cq_arm_doorbell_idx(struct arbel * arbel,struct ib_completion_queue * cq)612 arbel_cq_arm_doorbell_idx ( struct arbel *arbel,
613 			    struct ib_completion_queue *cq ) {
614 	return ( cq->cqn - arbel->limits.reserved_cqs );
615 }
616 
617 /**
618  * Get send work request doorbell index
619  *
620  * @v arbel		Arbel device
621  * @v qp		Queue pair
622  * @ret doorbell_idx	Doorbell index
623  */
624 static inline unsigned int
arbel_send_doorbell_idx(struct arbel * arbel,struct ib_queue_pair * qp)625 arbel_send_doorbell_idx ( struct arbel *arbel, struct ib_queue_pair *qp ) {
626 	return ( ARBEL_MAX_CQS +
627 		 ( ( qp->qpn & ~ARBEL_QPN_RANDOM_MASK ) -
628 		   arbel->special_qpn_base ) );
629 }
630 
631 /**
632  * Get receive work request doorbell index
633  *
634  * @v arbel		Arbel device
635  * @v qp		Queue pair
636  * @ret doorbell_idx	Doorbell index
637  */
638 static inline unsigned int
arbel_recv_doorbell_idx(struct arbel * arbel,struct ib_queue_pair * qp)639 arbel_recv_doorbell_idx ( struct arbel *arbel, struct ib_queue_pair *qp ) {
640 	return ( ARBEL_MAX_DOORBELL_RECORDS - ARBEL_MAX_CQS -
641 		 ( ( qp->qpn & ~ARBEL_QPN_RANDOM_MASK ) -
642 		   arbel->special_qpn_base ) - 1 );
643 }
644 
645 /**
646  * Get completion queue consumer counter doorbell index
647  *
648  * @v arbel		Arbel device
649  * @v cq		Completion queue
650  * @ret doorbell_idx	Doorbell index
651  */
652 static inline unsigned int
arbel_cq_ci_doorbell_idx(struct arbel * arbel,struct ib_completion_queue * cq)653 arbel_cq_ci_doorbell_idx ( struct arbel *arbel,
654 			   struct ib_completion_queue *cq ) {
655 	return ( ARBEL_MAX_DOORBELL_RECORDS -
656 		 ( cq->cqn - arbel->limits.reserved_cqs ) - 1 );
657 }
658 
659 #endif /* _ARBEL_H */
660