|
|
1.1 root 1: /*
2: * Copyright (C) 2008 Michael Brown <[email protected]>.
3: * Copyright (C) 2008 Mellanox Technologies Ltd.
4: *
5: * This program is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU General Public License as
7: * published by the Free Software Foundation; either version 2 of the
8: * License, or any later version.
9: *
10: * This program is distributed in the hope that it will be useful, but
11: * WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: * General Public License for more details.
14: *
15: * You should have received a copy of the GNU General Public License
16: * along with this program; if not, write to the Free Software
17: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18: */
19:
20: FILE_LICENCE ( GPL2_OR_LATER );
21:
22: #include <stdint.h>
23: #include <stdlib.h>
24: #include <stdio.h>
25: #include <string.h>
26: #include <strings.h>
27: #include <unistd.h>
28: #include <errno.h>
29: #include <byteswap.h>
30: #include <ipxe/io.h>
31: #include <ipxe/pci.h>
32: #include <ipxe/pcibackup.h>
33: #include <ipxe/malloc.h>
34: #include <ipxe/umalloc.h>
35: #include <ipxe/iobuf.h>
36: #include <ipxe/netdevice.h>
37: #include <ipxe/infiniband.h>
38: #include <ipxe/ib_smc.h>
39: #include <ipxe/if_ether.h>
40: #include <ipxe/ethernet.h>
41: #include <ipxe/fcoe.h>
42: #include <ipxe/vlan.h>
43: #include <ipxe/bofm.h>
44: #include "hermon.h"
45:
46: /**
47: * @file
48: *
49: * Mellanox Hermon Infiniband HCA
50: *
51: */
52:
53: /***************************************************************************
54: *
55: * Queue number allocation
56: *
57: ***************************************************************************
58: */
59:
60: /**
61: * Allocate offsets within usage bitmask
62: *
63: * @v bits Usage bitmask
64: * @v bits_len Length of usage bitmask
65: * @v num_bits Number of contiguous bits to allocate within bitmask
66: * @ret bit First free bit within bitmask, or negative error
67: */
68: static int hermon_bitmask_alloc ( hermon_bitmask_t *bits,
69: unsigned int bits_len,
70: unsigned int num_bits ) {
71: unsigned int bit = 0;
72: hermon_bitmask_t mask = 1;
73: unsigned int found = 0;
74:
75: /* Search bits for num_bits contiguous free bits */
76: while ( bit < bits_len ) {
77: if ( ( mask & *bits ) == 0 ) {
78: if ( ++found == num_bits )
79: goto found;
80: } else {
81: found = 0;
82: }
83: bit++;
84: mask = ( mask << 1 ) | ( mask >> ( 8 * sizeof ( mask ) - 1 ) );
85: if ( mask == 1 )
86: bits++;
87: }
88: return -ENFILE;
89:
90: found:
91: /* Mark bits as in-use */
92: do {
93: *bits |= mask;
94: if ( mask == 1 )
95: bits--;
96: mask = ( mask >> 1 ) | ( mask << ( 8 * sizeof ( mask ) - 1 ) );
97: } while ( --found );
98:
99: return ( bit - num_bits + 1 );
100: }
101:
102: /**
103: * Free offsets within usage bitmask
104: *
105: * @v bits Usage bitmask
106: * @v bit Starting bit within bitmask
107: * @v num_bits Number of contiguous bits to free within bitmask
108: */
109: static void hermon_bitmask_free ( hermon_bitmask_t *bits,
110: int bit, unsigned int num_bits ) {
111: hermon_bitmask_t mask;
112:
113: for ( ; num_bits ; bit++, num_bits-- ) {
114: mask = ( 1 << ( bit % ( 8 * sizeof ( mask ) ) ) );
115: bits[ ( bit / ( 8 * sizeof ( mask ) ) ) ] &= ~mask;
116: }
117: }
118:
119: /***************************************************************************
120: *
121: * HCA commands
122: *
123: ***************************************************************************
124: */
125:
126: /**
127: * Wait for Hermon command completion
128: *
129: * @v hermon Hermon device
130: * @v hcr HCA command registers
131: * @ret rc Return status code
132: */
133: static int hermon_cmd_wait ( struct hermon *hermon,
134: struct hermonprm_hca_command_register *hcr ) {
135: unsigned int wait;
136:
137: for ( wait = HERMON_HCR_MAX_WAIT_MS ; wait ; wait-- ) {
138: hcr->u.dwords[6] =
139: readl ( hermon->config + HERMON_HCR_REG ( 6 ) );
140: if ( ( MLX_GET ( hcr, go ) == 0 ) &&
141: ( MLX_GET ( hcr, t ) == hermon->toggle ) )
142: return 0;
143: mdelay ( 1 );
144: }
145: return -EBUSY;
146: }
147:
148: /**
149: * Issue HCA command
150: *
151: * @v hermon Hermon device
152: * @v command Command opcode, flags and input/output lengths
153: * @v op_mod Opcode modifier (0 if no modifier applicable)
154: * @v in Input parameters
155: * @v in_mod Input modifier (0 if no modifier applicable)
156: * @v out Output parameters
157: * @ret rc Return status code
158: */
159: static int hermon_cmd ( struct hermon *hermon, unsigned long command,
160: unsigned int op_mod, const void *in,
161: unsigned int in_mod, void *out ) {
162: struct hermonprm_hca_command_register hcr;
163: unsigned int opcode = HERMON_HCR_OPCODE ( command );
164: size_t in_len = HERMON_HCR_IN_LEN ( command );
165: size_t out_len = HERMON_HCR_OUT_LEN ( command );
166: void *in_buffer;
167: void *out_buffer;
168: unsigned int status;
169: unsigned int i;
170: int rc;
171:
172: assert ( in_len <= HERMON_MBOX_SIZE );
173: assert ( out_len <= HERMON_MBOX_SIZE );
174:
175: DBGC2 ( hermon, "Hermon %p command %02x in %zx%s out %zx%s\n",
176: hermon, opcode, in_len,
177: ( ( command & HERMON_HCR_IN_MBOX ) ? "(mbox)" : "" ), out_len,
178: ( ( command & HERMON_HCR_OUT_MBOX ) ? "(mbox)" : "" ) );
179:
180: /* Check that HCR is free */
181: if ( ( rc = hermon_cmd_wait ( hermon, &hcr ) ) != 0 ) {
182: DBGC ( hermon, "Hermon %p command interface locked\n",
183: hermon );
184: return rc;
185: }
186:
187: /* Flip HCR toggle */
188: hermon->toggle = ( 1 - hermon->toggle );
189:
190: /* Prepare HCR */
191: memset ( &hcr, 0, sizeof ( hcr ) );
192: in_buffer = &hcr.u.dwords[0];
193: if ( in_len && ( command & HERMON_HCR_IN_MBOX ) ) {
194: memset ( hermon->mailbox_in, 0, HERMON_MBOX_SIZE );
195: in_buffer = hermon->mailbox_in;
196: MLX_FILL_H ( &hcr, 0, in_param_h, virt_to_bus ( in_buffer ) );
197: MLX_FILL_1 ( &hcr, 1, in_param_l, virt_to_bus ( in_buffer ) );
198: }
199: memcpy ( in_buffer, in, in_len );
200: MLX_FILL_1 ( &hcr, 2, input_modifier, in_mod );
201: out_buffer = &hcr.u.dwords[3];
202: if ( out_len && ( command & HERMON_HCR_OUT_MBOX ) ) {
203: out_buffer = hermon->mailbox_out;
204: MLX_FILL_H ( &hcr, 3, out_param_h,
205: virt_to_bus ( out_buffer ) );
206: MLX_FILL_1 ( &hcr, 4, out_param_l,
207: virt_to_bus ( out_buffer ) );
208: }
209: MLX_FILL_4 ( &hcr, 6,
210: opcode, opcode,
211: opcode_modifier, op_mod,
212: go, 1,
213: t, hermon->toggle );
214: DBGC ( hermon, "Hermon %p issuing command %04x\n",
215: hermon, opcode );
216: DBGC2_HDA ( hermon, virt_to_phys ( hermon->config + HERMON_HCR_BASE ),
217: &hcr, sizeof ( hcr ) );
218: if ( in_len && ( command & HERMON_HCR_IN_MBOX ) ) {
219: DBGC2 ( hermon, "Input mailbox:\n" );
220: DBGC2_HDA ( hermon, virt_to_phys ( in_buffer ), in_buffer,
221: ( ( in_len < 512 ) ? in_len : 512 ) );
222: }
223:
224: /* Issue command */
225: for ( i = 0 ; i < ( sizeof ( hcr ) / sizeof ( hcr.u.dwords[0] ) ) ;
226: i++ ) {
227: writel ( hcr.u.dwords[i],
228: hermon->config + HERMON_HCR_REG ( i ) );
229: barrier();
230: }
231:
232: /* Wait for command completion */
233: if ( ( rc = hermon_cmd_wait ( hermon, &hcr ) ) != 0 ) {
234: DBGC ( hermon, "Hermon %p timed out waiting for command:\n",
235: hermon );
236: DBGC_HDA ( hermon,
237: virt_to_phys ( hermon->config + HERMON_HCR_BASE ),
238: &hcr, sizeof ( hcr ) );
239: return rc;
240: }
241:
242: /* Check command status */
243: status = MLX_GET ( &hcr, status );
244: if ( status != 0 ) {
245: DBGC ( hermon, "Hermon %p command failed with status %02x:\n",
246: hermon, status );
247: DBGC_HDA ( hermon,
248: virt_to_phys ( hermon->config + HERMON_HCR_BASE ),
249: &hcr, sizeof ( hcr ) );
250: return -EIO;
251: }
252:
253: /* Read output parameters, if any */
254: hcr.u.dwords[3] = readl ( hermon->config + HERMON_HCR_REG ( 3 ) );
255: hcr.u.dwords[4] = readl ( hermon->config + HERMON_HCR_REG ( 4 ) );
256: memcpy ( out, out_buffer, out_len );
257: if ( out_len ) {
258: DBGC2 ( hermon, "Output%s:\n",
259: ( command & HERMON_HCR_OUT_MBOX ) ? " mailbox" : "" );
260: DBGC2_HDA ( hermon, virt_to_phys ( out_buffer ), out_buffer,
261: ( ( out_len < 512 ) ? out_len : 512 ) );
262: }
263:
264: return 0;
265: }
266:
267: static inline int
268: hermon_cmd_query_dev_cap ( struct hermon *hermon,
269: struct hermonprm_query_dev_cap *dev_cap ) {
270: return hermon_cmd ( hermon,
271: HERMON_HCR_OUT_CMD ( HERMON_HCR_QUERY_DEV_CAP,
272: 1, sizeof ( *dev_cap ) ),
273: 0, NULL, 0, dev_cap );
274: }
275:
276: static inline int
277: hermon_cmd_query_fw ( struct hermon *hermon, struct hermonprm_query_fw *fw ) {
278: return hermon_cmd ( hermon,
279: HERMON_HCR_OUT_CMD ( HERMON_HCR_QUERY_FW,
280: 1, sizeof ( *fw ) ),
281: 0, NULL, 0, fw );
282: }
283:
284: static inline int
285: hermon_cmd_init_hca ( struct hermon *hermon,
286: const struct hermonprm_init_hca *init_hca ) {
287: return hermon_cmd ( hermon,
288: HERMON_HCR_IN_CMD ( HERMON_HCR_INIT_HCA,
289: 1, sizeof ( *init_hca ) ),
290: 0, init_hca, 0, NULL );
291: }
292:
293: static inline int
294: hermon_cmd_close_hca ( struct hermon *hermon ) {
295: return hermon_cmd ( hermon,
296: HERMON_HCR_VOID_CMD ( HERMON_HCR_CLOSE_HCA ),
297: 0, NULL, 0, NULL );
298: }
299:
300: static inline int
301: hermon_cmd_init_port ( struct hermon *hermon, unsigned int port ) {
302: return hermon_cmd ( hermon,
303: HERMON_HCR_VOID_CMD ( HERMON_HCR_INIT_PORT ),
304: 0, NULL, port, NULL );
305: }
306:
307: static inline int
308: hermon_cmd_close_port ( struct hermon *hermon, unsigned int port ) {
309: return hermon_cmd ( hermon,
310: HERMON_HCR_VOID_CMD ( HERMON_HCR_CLOSE_PORT ),
311: 0, NULL, port, NULL );
312: }
313:
314: static inline int
315: hermon_cmd_set_port ( struct hermon *hermon, int is_ethernet,
316: unsigned int port_selector,
317: const union hermonprm_set_port *set_port ) {
318: return hermon_cmd ( hermon,
319: HERMON_HCR_IN_CMD ( HERMON_HCR_SET_PORT,
320: 1, sizeof ( *set_port ) ),
321: is_ethernet, set_port, port_selector, NULL );
322: }
323:
324: static inline int
325: hermon_cmd_sw2hw_mpt ( struct hermon *hermon, unsigned int index,
326: const struct hermonprm_mpt *mpt ) {
327: return hermon_cmd ( hermon,
328: HERMON_HCR_IN_CMD ( HERMON_HCR_SW2HW_MPT,
329: 1, sizeof ( *mpt ) ),
330: 0, mpt, index, NULL );
331: }
332:
333: static inline int
334: hermon_cmd_write_mtt ( struct hermon *hermon,
335: const struct hermonprm_write_mtt *write_mtt ) {
336: return hermon_cmd ( hermon,
337: HERMON_HCR_IN_CMD ( HERMON_HCR_WRITE_MTT,
338: 1, sizeof ( *write_mtt ) ),
339: 0, write_mtt, 1, NULL );
340: }
341:
342: static inline int
343: hermon_cmd_map_eq ( struct hermon *hermon, unsigned long index_map,
344: const struct hermonprm_event_mask *mask ) {
345: return hermon_cmd ( hermon,
346: HERMON_HCR_IN_CMD ( HERMON_HCR_MAP_EQ,
347: 0, sizeof ( *mask ) ),
348: 0, mask, index_map, NULL );
349: }
350:
351: static inline int
352: hermon_cmd_sw2hw_eq ( struct hermon *hermon, unsigned int index,
353: const struct hermonprm_eqc *eqctx ) {
354: return hermon_cmd ( hermon,
355: HERMON_HCR_IN_CMD ( HERMON_HCR_SW2HW_EQ,
356: 1, sizeof ( *eqctx ) ),
357: 0, eqctx, index, NULL );
358: }
359:
360: static inline int
361: hermon_cmd_hw2sw_eq ( struct hermon *hermon, unsigned int index,
362: struct hermonprm_eqc *eqctx ) {
363: return hermon_cmd ( hermon,
364: HERMON_HCR_OUT_CMD ( HERMON_HCR_HW2SW_EQ,
365: 1, sizeof ( *eqctx ) ),
366: 1, NULL, index, eqctx );
367: }
368:
369: static inline int
370: hermon_cmd_query_eq ( struct hermon *hermon, unsigned int index,
371: struct hermonprm_eqc *eqctx ) {
372: return hermon_cmd ( hermon,
373: HERMON_HCR_OUT_CMD ( HERMON_HCR_QUERY_EQ,
374: 1, sizeof ( *eqctx ) ),
375: 0, NULL, index, eqctx );
376: }
377:
378: static inline int
379: hermon_cmd_sw2hw_cq ( struct hermon *hermon, unsigned long cqn,
380: const struct hermonprm_completion_queue_context *cqctx ){
381: return hermon_cmd ( hermon,
382: HERMON_HCR_IN_CMD ( HERMON_HCR_SW2HW_CQ,
383: 1, sizeof ( *cqctx ) ),
384: 0, cqctx, cqn, NULL );
385: }
386:
387: static inline int
388: hermon_cmd_hw2sw_cq ( struct hermon *hermon, unsigned long cqn,
389: struct hermonprm_completion_queue_context *cqctx ) {
390: return hermon_cmd ( hermon,
391: HERMON_HCR_OUT_CMD ( HERMON_HCR_HW2SW_CQ,
392: 1, sizeof ( *cqctx ) ),
393: 0, NULL, cqn, cqctx );
394: }
395:
396: static inline int
397: hermon_cmd_query_cq ( struct hermon *hermon, unsigned long cqn,
398: struct hermonprm_completion_queue_context *cqctx ) {
399: return hermon_cmd ( hermon,
400: HERMON_HCR_OUT_CMD ( HERMON_HCR_QUERY_CQ,
401: 1, sizeof ( *cqctx ) ),
402: 0, NULL, cqn, cqctx );
403: }
404:
405: static inline int
406: hermon_cmd_rst2init_qp ( struct hermon *hermon, unsigned long qpn,
407: const struct hermonprm_qp_ee_state_transitions *ctx ){
408: return hermon_cmd ( hermon,
409: HERMON_HCR_IN_CMD ( HERMON_HCR_RST2INIT_QP,
410: 1, sizeof ( *ctx ) ),
411: 0, ctx, qpn, NULL );
412: }
413:
414: static inline int
415: hermon_cmd_init2rtr_qp ( struct hermon *hermon, unsigned long qpn,
416: const struct hermonprm_qp_ee_state_transitions *ctx ){
417: return hermon_cmd ( hermon,
418: HERMON_HCR_IN_CMD ( HERMON_HCR_INIT2RTR_QP,
419: 1, sizeof ( *ctx ) ),
420: 0, ctx, qpn, NULL );
421: }
422:
423: static inline int
424: hermon_cmd_rtr2rts_qp ( struct hermon *hermon, unsigned long qpn,
425: const struct hermonprm_qp_ee_state_transitions *ctx ) {
426: return hermon_cmd ( hermon,
427: HERMON_HCR_IN_CMD ( HERMON_HCR_RTR2RTS_QP,
428: 1, sizeof ( *ctx ) ),
429: 0, ctx, qpn, NULL );
430: }
431:
432: static inline int
433: hermon_cmd_rts2rts_qp ( struct hermon *hermon, unsigned long qpn,
434: const struct hermonprm_qp_ee_state_transitions *ctx ) {
435: return hermon_cmd ( hermon,
436: HERMON_HCR_IN_CMD ( HERMON_HCR_RTS2RTS_QP,
437: 1, sizeof ( *ctx ) ),
438: 0, ctx, qpn, NULL );
439: }
440:
441: static inline int
442: hermon_cmd_2rst_qp ( struct hermon *hermon, unsigned long qpn ) {
443: return hermon_cmd ( hermon,
444: HERMON_HCR_VOID_CMD ( HERMON_HCR_2RST_QP ),
445: 0x03, NULL, qpn, NULL );
446: }
447:
448: static inline int
449: hermon_cmd_query_qp ( struct hermon *hermon, unsigned long qpn,
450: struct hermonprm_qp_ee_state_transitions *ctx ) {
451: return hermon_cmd ( hermon,
452: HERMON_HCR_OUT_CMD ( HERMON_HCR_QUERY_QP,
453: 1, sizeof ( *ctx ) ),
454: 0, NULL, qpn, ctx );
455: }
456:
457: static inline int
458: hermon_cmd_conf_special_qp ( struct hermon *hermon, unsigned int internal_qps,
459: unsigned long base_qpn ) {
460: return hermon_cmd ( hermon,
461: HERMON_HCR_VOID_CMD ( HERMON_HCR_CONF_SPECIAL_QP ),
462: internal_qps, NULL, base_qpn, NULL );
463: }
464:
465: static inline int
466: hermon_cmd_mad_ifc ( struct hermon *hermon, unsigned int port,
467: union hermonprm_mad *mad ) {
468: return hermon_cmd ( hermon,
469: HERMON_HCR_INOUT_CMD ( HERMON_HCR_MAD_IFC,
470: 1, sizeof ( *mad ),
471: 1, sizeof ( *mad ) ),
472: 0x03, mad, port, mad );
473: }
474:
475: static inline int
476: hermon_cmd_read_mcg ( struct hermon *hermon, unsigned int index,
477: struct hermonprm_mcg_entry *mcg ) {
478: return hermon_cmd ( hermon,
479: HERMON_HCR_OUT_CMD ( HERMON_HCR_READ_MCG,
480: 1, sizeof ( *mcg ) ),
481: 0, NULL, index, mcg );
482: }
483:
484: static inline int
485: hermon_cmd_write_mcg ( struct hermon *hermon, unsigned int index,
486: const struct hermonprm_mcg_entry *mcg ) {
487: return hermon_cmd ( hermon,
488: HERMON_HCR_IN_CMD ( HERMON_HCR_WRITE_MCG,
489: 1, sizeof ( *mcg ) ),
490: 0, mcg, index, NULL );
491: }
492:
493: static inline int
494: hermon_cmd_mgid_hash ( struct hermon *hermon, const union ib_gid *gid,
495: struct hermonprm_mgm_hash *hash ) {
496: return hermon_cmd ( hermon,
497: HERMON_HCR_INOUT_CMD ( HERMON_HCR_MGID_HASH,
498: 1, sizeof ( *gid ),
499: 0, sizeof ( *hash ) ),
500: 0, gid, 0, hash );
501: }
502:
503: static inline int
504: hermon_cmd_mod_stat_cfg ( struct hermon *hermon, unsigned int mode,
505: unsigned int input_mod,
506: struct hermonprm_scalar_parameter *portion ) {
507: return hermon_cmd ( hermon,
508: HERMON_HCR_INOUT_CMD ( HERMON_HCR_MOD_STAT_CFG,
509: 0, sizeof ( *portion ),
510: 0, sizeof ( *portion ) ),
511: mode, portion, input_mod, portion );
512: }
513:
514: static inline int
515: hermon_cmd_query_port ( struct hermon *hermon, unsigned int port,
516: struct hermonprm_query_port_cap *query_port ) {
517: return hermon_cmd ( hermon,
518: HERMON_HCR_OUT_CMD ( HERMON_HCR_QUERY_PORT,
519: 1, sizeof ( *query_port ) ),
520: 0, NULL, port, query_port );
521: }
522:
523: static inline int
524: hermon_cmd_sense_port ( struct hermon *hermon, unsigned int port,
525: struct hermonprm_sense_port *port_type ) {
526: return hermon_cmd ( hermon,
527: HERMON_HCR_OUT_CMD ( HERMON_HCR_SENSE_PORT,
528: 0, sizeof ( *port_type ) ),
529: 0, NULL, port, port_type );
530: }
531:
532: static inline int
533: hermon_cmd_run_fw ( struct hermon *hermon ) {
534: return hermon_cmd ( hermon,
535: HERMON_HCR_VOID_CMD ( HERMON_HCR_RUN_FW ),
536: 0, NULL, 0, NULL );
537: }
538:
539: static inline int
540: hermon_cmd_unmap_icm ( struct hermon *hermon, unsigned int page_count,
541: const struct hermonprm_scalar_parameter *offset ) {
542: return hermon_cmd ( hermon,
543: HERMON_HCR_IN_CMD ( HERMON_HCR_UNMAP_ICM,
544: 0, sizeof ( *offset ) ),
545: 0, offset, page_count, NULL );
546: }
547:
548: static inline int
549: hermon_cmd_map_icm ( struct hermon *hermon,
550: const struct hermonprm_virtual_physical_mapping *map ) {
551: return hermon_cmd ( hermon,
552: HERMON_HCR_IN_CMD ( HERMON_HCR_MAP_ICM,
553: 1, sizeof ( *map ) ),
554: 0, map, 1, NULL );
555: }
556:
557: static inline int
558: hermon_cmd_unmap_icm_aux ( struct hermon *hermon ) {
559: return hermon_cmd ( hermon,
560: HERMON_HCR_VOID_CMD ( HERMON_HCR_UNMAP_ICM_AUX ),
561: 0, NULL, 0, NULL );
562: }
563:
564: static inline int
565: hermon_cmd_map_icm_aux ( struct hermon *hermon,
566: const struct hermonprm_virtual_physical_mapping *map ) {
567: return hermon_cmd ( hermon,
568: HERMON_HCR_IN_CMD ( HERMON_HCR_MAP_ICM_AUX,
569: 1, sizeof ( *map ) ),
570: 0, map, 1, NULL );
571: }
572:
573: static inline int
574: hermon_cmd_set_icm_size ( struct hermon *hermon,
575: const struct hermonprm_scalar_parameter *icm_size,
576: struct hermonprm_scalar_parameter *icm_aux_size ) {
577: return hermon_cmd ( hermon,
578: HERMON_HCR_INOUT_CMD ( HERMON_HCR_SET_ICM_SIZE,
579: 0, sizeof ( *icm_size ),
580: 0, sizeof (*icm_aux_size) ),
581: 0, icm_size, 0, icm_aux_size );
582: }
583:
584: static inline int
585: hermon_cmd_unmap_fa ( struct hermon *hermon ) {
586: return hermon_cmd ( hermon,
587: HERMON_HCR_VOID_CMD ( HERMON_HCR_UNMAP_FA ),
588: 0, NULL, 0, NULL );
589: }
590:
591: static inline int
592: hermon_cmd_map_fa ( struct hermon *hermon,
593: const struct hermonprm_virtual_physical_mapping *map ) {
594: return hermon_cmd ( hermon,
595: HERMON_HCR_IN_CMD ( HERMON_HCR_MAP_FA,
596: 1, sizeof ( *map ) ),
597: 0, map, 1, NULL );
598: }
599:
600: /***************************************************************************
601: *
602: * Memory translation table operations
603: *
604: ***************************************************************************
605: */
606:
607: /**
608: * Allocate MTT entries
609: *
610: * @v hermon Hermon device
611: * @v memory Memory to map into MTT
612: * @v len Length of memory to map
613: * @v mtt MTT descriptor to fill in
614: * @ret rc Return status code
615: */
616: static int hermon_alloc_mtt ( struct hermon *hermon,
617: const void *memory, size_t len,
618: struct hermon_mtt *mtt ) {
619: struct hermonprm_write_mtt write_mtt;
620: physaddr_t start;
621: physaddr_t addr;
622: unsigned int page_offset;
623: unsigned int num_pages;
624: int mtt_offset;
625: unsigned int mtt_base_addr;
626: unsigned int i;
627: int rc;
628:
629: /* Find available MTT entries */
630: start = virt_to_phys ( memory );
631: page_offset = ( start & ( HERMON_PAGE_SIZE - 1 ) );
632: start -= page_offset;
633: len += page_offset;
634: num_pages = ( ( len + HERMON_PAGE_SIZE - 1 ) / HERMON_PAGE_SIZE );
635: mtt_offset = hermon_bitmask_alloc ( hermon->mtt_inuse, HERMON_MAX_MTTS,
636: num_pages );
637: if ( mtt_offset < 0 ) {
638: DBGC ( hermon, "Hermon %p could not allocate %d MTT entries\n",
639: hermon, num_pages );
640: rc = mtt_offset;
641: goto err_mtt_offset;
642: }
643: mtt_base_addr = ( ( hermon->cap.reserved_mtts + mtt_offset ) *
644: hermon->cap.mtt_entry_size );
645: addr = start;
646:
647: /* Fill in MTT structure */
648: mtt->mtt_offset = mtt_offset;
649: mtt->num_pages = num_pages;
650: mtt->mtt_base_addr = mtt_base_addr;
651: mtt->page_offset = page_offset;
652:
653: /* Construct and issue WRITE_MTT commands */
654: for ( i = 0 ; i < num_pages ; i++ ) {
655: memset ( &write_mtt, 0, sizeof ( write_mtt ) );
656: MLX_FILL_1 ( &write_mtt.mtt_base_addr, 1,
657: value, mtt_base_addr );
658: MLX_FILL_H ( &write_mtt.mtt, 0, ptag_h, addr );
659: MLX_FILL_2 ( &write_mtt.mtt, 1,
660: p, 1,
661: ptag_l, ( addr >> 3 ) );
662: if ( ( rc = hermon_cmd_write_mtt ( hermon,
663: &write_mtt ) ) != 0 ) {
664: DBGC ( hermon, "Hermon %p could not write MTT at %x\n",
665: hermon, mtt_base_addr );
666: goto err_write_mtt;
667: }
668: addr += HERMON_PAGE_SIZE;
669: mtt_base_addr += hermon->cap.mtt_entry_size;
670: }
671:
672: DBGC ( hermon, "Hermon %p MTT entries [%#x,%#x] for "
673: "[%08lx,%08lx,%08lx,%08lx)\n", hermon, mtt->mtt_offset,
674: ( mtt->mtt_offset + mtt->num_pages - 1 ), start,
675: ( start + page_offset ), ( start + len ), addr );
676:
677: return 0;
678:
679: err_write_mtt:
680: hermon_bitmask_free ( hermon->mtt_inuse, mtt_offset, num_pages );
681: err_mtt_offset:
682: return rc;
683: }
684:
685: /**
686: * Free MTT entries
687: *
688: * @v hermon Hermon device
689: * @v mtt MTT descriptor
690: */
691: static void hermon_free_mtt ( struct hermon *hermon,
692: struct hermon_mtt *mtt ) {
693:
694: DBGC ( hermon, "Hermon %p MTT entries [%#x,%#x] freed\n",
695: hermon, mtt->mtt_offset,
696: ( mtt->mtt_offset + mtt->num_pages - 1 ) );
697: hermon_bitmask_free ( hermon->mtt_inuse, mtt->mtt_offset,
698: mtt->num_pages );
699: }
700:
701: /***************************************************************************
702: *
703: * Static configuration operations
704: *
705: ***************************************************************************
706: */
707:
708: /**
709: * Calculate offset within static configuration
710: *
711: * @v field Field
712: * @ret offset Offset
713: */
714: #define HERMON_MOD_STAT_CFG_OFFSET( field ) \
715: ( ( MLX_BIT_OFFSET ( struct hermonprm_mod_stat_cfg_st, field ) / 8 ) \
716: & ~( sizeof ( struct hermonprm_scalar_parameter ) - 1 ) )
717:
718: /**
719: * Query or modify static configuration
720: *
721: * @v hermon Hermon device
722: * @v port Port
723: * @v mode Command mode
724: * @v offset Offset within static configuration
725: * @v stat_cfg Static configuration
726: * @ret rc Return status code
727: */
728: static int hermon_mod_stat_cfg ( struct hermon *hermon, unsigned int port,
729: unsigned int mode, unsigned int offset,
730: struct hermonprm_mod_stat_cfg *stat_cfg ) {
731: struct hermonprm_scalar_parameter *portion =
732: ( ( void * ) &stat_cfg->u.bytes[offset] );
733: struct hermonprm_mod_stat_cfg_input_mod mod;
734: int rc;
735:
736: /* Sanity check */
737: assert ( ( offset % sizeof ( *portion ) ) == 0 );
738:
739: /* Construct input modifier */
740: memset ( &mod, 0, sizeof ( mod ) );
741: MLX_FILL_2 ( &mod, 0,
742: portnum, port,
743: offset, offset );
744:
745: /* Issue command */
746: if ( ( rc = hermon_cmd_mod_stat_cfg ( hermon, mode,
747: be32_to_cpu ( mod.u.dwords[0] ),
748: portion ) ) != 0 )
749: return rc;
750:
751: return 0;
752: }
753:
754: /***************************************************************************
755: *
756: * MAD operations
757: *
758: ***************************************************************************
759: */
760:
761: /**
762: * Issue management datagram
763: *
764: * @v ibdev Infiniband device
765: * @v mad Management datagram
766: * @ret rc Return status code
767: */
768: static int hermon_mad ( struct ib_device *ibdev, union ib_mad *mad ) {
769: struct hermon *hermon = ib_get_drvdata ( ibdev );
770: union hermonprm_mad mad_ifc;
771: int rc;
772:
773: linker_assert ( sizeof ( *mad ) == sizeof ( mad_ifc.mad ),
774: mad_size_mismatch );
775:
776: /* Copy in request packet */
777: memcpy ( &mad_ifc.mad, mad, sizeof ( mad_ifc.mad ) );
778:
779: /* Issue MAD */
780: if ( ( rc = hermon_cmd_mad_ifc ( hermon, ibdev->port,
781: &mad_ifc ) ) != 0 ) {
782: DBGC ( hermon, "Hermon %p port %d could not issue MAD IFC: "
783: "%s\n", hermon, ibdev->port, strerror ( rc ) );
784: return rc;
785: }
786:
787: /* Copy out reply packet */
788: memcpy ( mad, &mad_ifc.mad, sizeof ( *mad ) );
789:
790: if ( mad->hdr.status != 0 ) {
791: DBGC ( hermon, "Hermon %p port %d MAD IFC status %04x\n",
792: hermon, ibdev->port, ntohs ( mad->hdr.status ) );
793: return -EIO;
794: }
795: return 0;
796: }
797:
798: /***************************************************************************
799: *
800: * Completion queue operations
801: *
802: ***************************************************************************
803: */
804:
805: /**
806: * Dump completion queue context (for debugging only)
807: *
808: * @v hermon Hermon device
809: * @v cq Completion queue
810: * @ret rc Return status code
811: */
812: static __attribute__ (( unused )) int
813: hermon_dump_cqctx ( struct hermon *hermon, struct ib_completion_queue *cq ) {
814: struct hermonprm_completion_queue_context cqctx;
815: int rc;
816:
817: memset ( &cqctx, 0, sizeof ( cqctx ) );
818: if ( ( rc = hermon_cmd_query_cq ( hermon, cq->cqn, &cqctx ) ) != 0 ) {
819: DBGC ( hermon, "Hermon %p CQN %#lx QUERY_CQ failed: %s\n",
820: hermon, cq->cqn, strerror ( rc ) );
821: return rc;
822: }
823: DBGC ( hermon, "Hermon %p CQN %#lx context:\n", hermon, cq->cqn );
824: DBGC_HDA ( hermon, 0, &cqctx, sizeof ( cqctx ) );
825:
826: return 0;
827: }
828:
829: /**
830: * Create completion queue
831: *
832: * @v ibdev Infiniband device
833: * @v cq Completion queue
834: * @ret rc Return status code
835: */
836: static int hermon_create_cq ( struct ib_device *ibdev,
837: struct ib_completion_queue *cq ) {
838: struct hermon *hermon = ib_get_drvdata ( ibdev );
839: struct hermon_completion_queue *hermon_cq;
840: struct hermonprm_completion_queue_context cqctx;
841: int cqn_offset;
842: unsigned int i;
843: int rc;
844:
845: /* Find a free completion queue number */
846: cqn_offset = hermon_bitmask_alloc ( hermon->cq_inuse,
847: HERMON_MAX_CQS, 1 );
848: if ( cqn_offset < 0 ) {
849: DBGC ( hermon, "Hermon %p out of completion queues\n",
850: hermon );
851: rc = cqn_offset;
852: goto err_cqn_offset;
853: }
854: cq->cqn = ( hermon->cap.reserved_cqs + cqn_offset );
855:
856: /* Allocate control structures */
857: hermon_cq = zalloc ( sizeof ( *hermon_cq ) );
858: if ( ! hermon_cq ) {
859: rc = -ENOMEM;
860: goto err_hermon_cq;
861: }
862:
863: /* Allocate doorbell */
864: hermon_cq->doorbell = malloc_dma ( sizeof ( hermon_cq->doorbell[0] ),
865: sizeof ( hermon_cq->doorbell[0] ) );
866: if ( ! hermon_cq->doorbell ) {
867: rc = -ENOMEM;
868: goto err_doorbell;
869: }
870: memset ( hermon_cq->doorbell, 0, sizeof ( hermon_cq->doorbell[0] ) );
871:
872: /* Allocate completion queue itself */
873: hermon_cq->cqe_size = ( cq->num_cqes * sizeof ( hermon_cq->cqe[0] ) );
874: hermon_cq->cqe = malloc_dma ( hermon_cq->cqe_size,
875: sizeof ( hermon_cq->cqe[0] ) );
876: if ( ! hermon_cq->cqe ) {
877: rc = -ENOMEM;
878: goto err_cqe;
879: }
880: memset ( hermon_cq->cqe, 0, hermon_cq->cqe_size );
881: for ( i = 0 ; i < cq->num_cqes ; i++ ) {
882: MLX_FILL_1 ( &hermon_cq->cqe[i].normal, 7, owner, 1 );
883: }
884: barrier();
885:
886: /* Allocate MTT entries */
887: if ( ( rc = hermon_alloc_mtt ( hermon, hermon_cq->cqe,
888: hermon_cq->cqe_size,
889: &hermon_cq->mtt ) ) != 0 )
890: goto err_alloc_mtt;
891:
892: /* Hand queue over to hardware */
893: memset ( &cqctx, 0, sizeof ( cqctx ) );
894: MLX_FILL_1 ( &cqctx, 0, st, 0xa /* "Event fired" */ );
895: MLX_FILL_1 ( &cqctx, 2,
896: page_offset, ( hermon_cq->mtt.page_offset >> 5 ) );
897: MLX_FILL_2 ( &cqctx, 3,
898: usr_page, HERMON_UAR_NON_EQ_PAGE,
899: log_cq_size, fls ( cq->num_cqes - 1 ) );
900: MLX_FILL_1 ( &cqctx, 5, c_eqn, hermon->eq.eqn );
901: MLX_FILL_H ( &cqctx, 6, mtt_base_addr_h,
902: hermon_cq->mtt.mtt_base_addr );
903: MLX_FILL_1 ( &cqctx, 7, mtt_base_addr_l,
904: ( hermon_cq->mtt.mtt_base_addr >> 3 ) );
905: MLX_FILL_H ( &cqctx, 14, db_record_addr_h,
906: virt_to_phys ( hermon_cq->doorbell ) );
907: MLX_FILL_1 ( &cqctx, 15, db_record_addr_l,
908: ( virt_to_phys ( hermon_cq->doorbell ) >> 3 ) );
909: if ( ( rc = hermon_cmd_sw2hw_cq ( hermon, cq->cqn, &cqctx ) ) != 0 ) {
910: DBGC ( hermon, "Hermon %p CQN %#lx SW2HW_CQ failed: %s\n",
911: hermon, cq->cqn, strerror ( rc ) );
912: goto err_sw2hw_cq;
913: }
914:
915: DBGC ( hermon, "Hermon %p CQN %#lx ring [%08lx,%08lx), doorbell "
916: "%08lx\n", hermon, cq->cqn, virt_to_phys ( hermon_cq->cqe ),
917: ( virt_to_phys ( hermon_cq->cqe ) + hermon_cq->cqe_size ),
918: virt_to_phys ( hermon_cq->doorbell ) );
919: ib_cq_set_drvdata ( cq, hermon_cq );
920: return 0;
921:
922: err_sw2hw_cq:
923: hermon_free_mtt ( hermon, &hermon_cq->mtt );
924: err_alloc_mtt:
925: free_dma ( hermon_cq->cqe, hermon_cq->cqe_size );
926: err_cqe:
927: free_dma ( hermon_cq->doorbell, sizeof ( hermon_cq->doorbell[0] ) );
928: err_doorbell:
929: free ( hermon_cq );
930: err_hermon_cq:
931: hermon_bitmask_free ( hermon->cq_inuse, cqn_offset, 1 );
932: err_cqn_offset:
933: return rc;
934: }
935:
936: /**
937: * Destroy completion queue
938: *
939: * @v ibdev Infiniband device
940: * @v cq Completion queue
941: */
942: static void hermon_destroy_cq ( struct ib_device *ibdev,
943: struct ib_completion_queue *cq ) {
944: struct hermon *hermon = ib_get_drvdata ( ibdev );
945: struct hermon_completion_queue *hermon_cq = ib_cq_get_drvdata ( cq );
946: struct hermonprm_completion_queue_context cqctx;
947: int cqn_offset;
948: int rc;
949:
950: /* Take ownership back from hardware */
951: if ( ( rc = hermon_cmd_hw2sw_cq ( hermon, cq->cqn, &cqctx ) ) != 0 ) {
952: DBGC ( hermon, "Hermon %p CQN %#lx FATAL HW2SW_CQ failed: "
953: "%s\n", hermon, cq->cqn, strerror ( rc ) );
954: /* Leak memory and return; at least we avoid corruption */
955: return;
956: }
957:
958: /* Free MTT entries */
959: hermon_free_mtt ( hermon, &hermon_cq->mtt );
960:
961: /* Free memory */
962: free_dma ( hermon_cq->cqe, hermon_cq->cqe_size );
963: free_dma ( hermon_cq->doorbell, sizeof ( hermon_cq->doorbell[0] ) );
964: free ( hermon_cq );
965:
966: /* Mark queue number as free */
967: cqn_offset = ( cq->cqn - hermon->cap.reserved_cqs );
968: hermon_bitmask_free ( hermon->cq_inuse, cqn_offset, 1 );
969:
970: ib_cq_set_drvdata ( cq, NULL );
971: }
972:
973: /***************************************************************************
974: *
975: * Queue pair operations
976: *
977: ***************************************************************************
978: */
979:
980: /**
981: * Assign queue pair number
982: *
983: * @v ibdev Infiniband device
984: * @v qp Queue pair
985: * @ret rc Return status code
986: */
987: static int hermon_alloc_qpn ( struct ib_device *ibdev,
988: struct ib_queue_pair *qp ) {
989: struct hermon *hermon = ib_get_drvdata ( ibdev );
990: unsigned int port_offset;
991: int qpn_offset;
992:
993: /* Calculate queue pair number */
994: port_offset = ( ibdev->port - HERMON_PORT_BASE );
995:
996: switch ( qp->type ) {
997: case IB_QPT_SMI:
998: qp->qpn = ( hermon->special_qpn_base + port_offset );
999: return 0;
1000: case IB_QPT_GSI:
1001: qp->qpn = ( hermon->special_qpn_base + 2 + port_offset );
1002: return 0;
1003: case IB_QPT_UD:
1004: case IB_QPT_RC:
1005: case IB_QPT_ETH:
1006: /* Find a free queue pair number */
1007: qpn_offset = hermon_bitmask_alloc ( hermon->qp_inuse,
1008: HERMON_MAX_QPS, 1 );
1009: if ( qpn_offset < 0 ) {
1010: DBGC ( hermon, "Hermon %p out of queue pairs\n",
1011: hermon );
1012: return qpn_offset;
1013: }
1014: qp->qpn = ( ( random() & HERMON_QPN_RANDOM_MASK ) |
1015: ( hermon->qpn_base + qpn_offset ) );
1016: return 0;
1017: default:
1018: DBGC ( hermon, "Hermon %p unsupported QP type %d\n",
1019: hermon, qp->type );
1020: return -ENOTSUP;
1021: }
1022: }
1023:
1024: /**
1025: * Free queue pair number
1026: *
1027: * @v ibdev Infiniband device
1028: * @v qp Queue pair
1029: */
1030: static void hermon_free_qpn ( struct ib_device *ibdev,
1031: struct ib_queue_pair *qp ) {
1032: struct hermon *hermon = ib_get_drvdata ( ibdev );
1033: int qpn_offset;
1034:
1035: qpn_offset = ( ( qp->qpn & ~HERMON_QPN_RANDOM_MASK )
1036: - hermon->qpn_base );
1037: if ( qpn_offset >= 0 )
1038: hermon_bitmask_free ( hermon->qp_inuse, qpn_offset, 1 );
1039: }
1040:
1041: /**
1042: * Calculate transmission rate
1043: *
1044: * @v av Address vector
1045: * @ret hermon_rate Hermon rate
1046: */
1047: static unsigned int hermon_rate ( struct ib_address_vector *av ) {
1048: return ( ( ( av->rate >= IB_RATE_2_5 ) && ( av->rate <= IB_RATE_120 ) )
1049: ? ( av->rate + 5 ) : 0 );
1050: }
1051:
1052: /**
1053: * Calculate schedule queue
1054: *
1055: * @v ibdev Infiniband device
1056: * @v qp Queue pair
1057: * @ret sched_queue Schedule queue
1058: */
1059: static unsigned int hermon_sched_queue ( struct ib_device *ibdev,
1060: struct ib_queue_pair *qp ) {
1061: return ( ( ( qp->type == IB_QPT_SMI ) ?
1062: HERMON_SCHED_QP0 : HERMON_SCHED_DEFAULT ) |
1063: ( ( ibdev->port - 1 ) << 6 ) );
1064: }
1065:
1066: /** Queue pair transport service type map */
1067: static uint8_t hermon_qp_st[] = {
1068: [IB_QPT_SMI] = HERMON_ST_MLX,
1069: [IB_QPT_GSI] = HERMON_ST_MLX,
1070: [IB_QPT_UD] = HERMON_ST_UD,
1071: [IB_QPT_RC] = HERMON_ST_RC,
1072: [IB_QPT_ETH] = HERMON_ST_MLX,
1073: };
1074:
1075: /**
1076: * Dump queue pair context (for debugging only)
1077: *
1078: * @v hermon Hermon device
1079: * @v qp Queue pair
1080: * @ret rc Return status code
1081: */
1082: static __attribute__ (( unused )) int
1083: hermon_dump_qpctx ( struct hermon *hermon, struct ib_queue_pair *qp ) {
1084: struct hermonprm_qp_ee_state_transitions qpctx;
1085: int rc;
1086:
1087: memset ( &qpctx, 0, sizeof ( qpctx ) );
1088: if ( ( rc = hermon_cmd_query_qp ( hermon, qp->qpn, &qpctx ) ) != 0 ) {
1089: DBGC ( hermon, "Hermon %p QPN %#lx QUERY_QP failed: %s\n",
1090: hermon, qp->qpn, strerror ( rc ) );
1091: return rc;
1092: }
1093: DBGC ( hermon, "Hermon %p QPN %#lx context:\n", hermon, qp->qpn );
1094: DBGC_HDA ( hermon, 0, &qpctx.u.dwords[2], ( sizeof ( qpctx ) - 8 ) );
1095:
1096: return 0;
1097: }
1098:
1099: /**
1100: * Create queue pair
1101: *
1102: * @v ibdev Infiniband device
1103: * @v qp Queue pair
1104: * @ret rc Return status code
1105: */
1106: static int hermon_create_qp ( struct ib_device *ibdev,
1107: struct ib_queue_pair *qp ) {
1108: struct hermon *hermon = ib_get_drvdata ( ibdev );
1109: struct hermon_queue_pair *hermon_qp;
1110: struct hermonprm_qp_ee_state_transitions qpctx;
1111: int rc;
1112:
1113: /* Calculate queue pair number */
1114: if ( ( rc = hermon_alloc_qpn ( ibdev, qp ) ) != 0 )
1115: goto err_alloc_qpn;
1116:
1117: /* Allocate control structures */
1118: hermon_qp = zalloc ( sizeof ( *hermon_qp ) );
1119: if ( ! hermon_qp ) {
1120: rc = -ENOMEM;
1121: goto err_hermon_qp;
1122: }
1123:
1124: /* Allocate doorbells */
1125: hermon_qp->recv.doorbell =
1126: malloc_dma ( sizeof ( hermon_qp->recv.doorbell[0] ),
1127: sizeof ( hermon_qp->recv.doorbell[0] ) );
1128: if ( ! hermon_qp->recv.doorbell ) {
1129: rc = -ENOMEM;
1130: goto err_recv_doorbell;
1131: }
1132: memset ( hermon_qp->recv.doorbell, 0,
1133: sizeof ( hermon_qp->recv.doorbell[0] ) );
1134: hermon_qp->send.doorbell =
1135: ( hermon->uar + HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE +
1136: HERMON_DB_POST_SND_OFFSET );
1137:
1138: /* Allocate work queue buffer */
1139: hermon_qp->send.num_wqes = ( qp->send.num_wqes /* headroom */ + 1 +
1140: ( 2048 / sizeof ( hermon_qp->send.wqe[0] ) ) );
1141: hermon_qp->send.num_wqes =
1142: ( 1 << fls ( hermon_qp->send.num_wqes - 1 ) ); /* round up */
1143: hermon_qp->send.wqe_size = ( hermon_qp->send.num_wqes *
1144: sizeof ( hermon_qp->send.wqe[0] ) );
1145: hermon_qp->recv.wqe_size = ( qp->recv.num_wqes *
1146: sizeof ( hermon_qp->recv.wqe[0] ) );
1147: hermon_qp->wqe_size = ( hermon_qp->send.wqe_size +
1148: hermon_qp->recv.wqe_size );
1149: hermon_qp->wqe = malloc_dma ( hermon_qp->wqe_size,
1150: sizeof ( hermon_qp->send.wqe[0] ) );
1151: if ( ! hermon_qp->wqe ) {
1152: rc = -ENOMEM;
1153: goto err_alloc_wqe;
1154: }
1155: hermon_qp->send.wqe = hermon_qp->wqe;
1156: memset ( hermon_qp->send.wqe, 0xff, hermon_qp->send.wqe_size );
1157: hermon_qp->recv.wqe = ( hermon_qp->wqe + hermon_qp->send.wqe_size );
1158: memset ( hermon_qp->recv.wqe, 0, hermon_qp->recv.wqe_size );
1159:
1160: /* Allocate MTT entries */
1161: if ( ( rc = hermon_alloc_mtt ( hermon, hermon_qp->wqe,
1162: hermon_qp->wqe_size,
1163: &hermon_qp->mtt ) ) != 0 ) {
1164: goto err_alloc_mtt;
1165: }
1166:
1167: /* Transition queue to INIT state */
1168: memset ( &qpctx, 0, sizeof ( qpctx ) );
1169: MLX_FILL_2 ( &qpctx, 2,
1170: qpc_eec_data.pm_state, HERMON_PM_STATE_MIGRATED,
1171: qpc_eec_data.st, hermon_qp_st[qp->type] );
1172: MLX_FILL_1 ( &qpctx, 3, qpc_eec_data.pd, HERMON_GLOBAL_PD );
1173: MLX_FILL_4 ( &qpctx, 4,
1174: qpc_eec_data.log_rq_size, fls ( qp->recv.num_wqes - 1 ),
1175: qpc_eec_data.log_rq_stride,
1176: ( fls ( sizeof ( hermon_qp->recv.wqe[0] ) - 1 ) - 4 ),
1177: qpc_eec_data.log_sq_size,
1178: fls ( hermon_qp->send.num_wqes - 1 ),
1179: qpc_eec_data.log_sq_stride,
1180: ( fls ( sizeof ( hermon_qp->send.wqe[0] ) - 1 ) - 4 ) );
1181: MLX_FILL_1 ( &qpctx, 5,
1182: qpc_eec_data.usr_page, HERMON_UAR_NON_EQ_PAGE );
1183: MLX_FILL_1 ( &qpctx, 33, qpc_eec_data.cqn_snd, qp->send.cq->cqn );
1184: MLX_FILL_4 ( &qpctx, 38,
1185: qpc_eec_data.rre, 1,
1186: qpc_eec_data.rwe, 1,
1187: qpc_eec_data.rae, 1,
1188: qpc_eec_data.page_offset,
1189: ( hermon_qp->mtt.page_offset >> 6 ) );
1190: MLX_FILL_1 ( &qpctx, 41, qpc_eec_data.cqn_rcv, qp->recv.cq->cqn );
1191: MLX_FILL_H ( &qpctx, 42, qpc_eec_data.db_record_addr_h,
1192: virt_to_phys ( hermon_qp->recv.doorbell ) );
1193: MLX_FILL_1 ( &qpctx, 43, qpc_eec_data.db_record_addr_l,
1194: ( virt_to_phys ( hermon_qp->recv.doorbell ) >> 2 ) );
1195: MLX_FILL_H ( &qpctx, 52, qpc_eec_data.mtt_base_addr_h,
1196: hermon_qp->mtt.mtt_base_addr );
1197: MLX_FILL_1 ( &qpctx, 53, qpc_eec_data.mtt_base_addr_l,
1198: ( hermon_qp->mtt.mtt_base_addr >> 3 ) );
1199: if ( ( rc = hermon_cmd_rst2init_qp ( hermon, qp->qpn,
1200: &qpctx ) ) != 0 ) {
1201: DBGC ( hermon, "Hermon %p QPN %#lx RST2INIT_QP failed: %s\n",
1202: hermon, qp->qpn, strerror ( rc ) );
1203: goto err_rst2init_qp;
1204: }
1205: hermon_qp->state = HERMON_QP_ST_INIT;
1206:
1207: DBGC ( hermon, "Hermon %p QPN %#lx send ring [%08lx,%08lx), doorbell "
1208: "%08lx\n", hermon, qp->qpn,
1209: virt_to_phys ( hermon_qp->send.wqe ),
1210: ( virt_to_phys ( hermon_qp->send.wqe ) +
1211: hermon_qp->send.wqe_size ),
1212: virt_to_phys ( hermon_qp->send.doorbell ) );
1213: DBGC ( hermon, "Hermon %p QPN %#lx receive ring [%08lx,%08lx), "
1214: "doorbell %08lx\n", hermon, qp->qpn,
1215: virt_to_phys ( hermon_qp->recv.wqe ),
1216: ( virt_to_phys ( hermon_qp->recv.wqe ) +
1217: hermon_qp->recv.wqe_size ),
1218: virt_to_phys ( hermon_qp->recv.doorbell ) );
1219: DBGC ( hermon, "Hermon %p QPN %#lx send CQN %#lx receive CQN %#lx\n",
1220: hermon, qp->qpn, qp->send.cq->cqn, qp->recv.cq->cqn );
1221: ib_qp_set_drvdata ( qp, hermon_qp );
1222: return 0;
1223:
1224: hermon_cmd_2rst_qp ( hermon, qp->qpn );
1225: err_rst2init_qp:
1226: hermon_free_mtt ( hermon, &hermon_qp->mtt );
1227: err_alloc_mtt:
1228: free_dma ( hermon_qp->wqe, hermon_qp->wqe_size );
1229: err_alloc_wqe:
1230: free_dma ( hermon_qp->recv.doorbell,
1231: sizeof ( hermon_qp->recv.doorbell[0] ) );
1232: err_recv_doorbell:
1233: free ( hermon_qp );
1234: err_hermon_qp:
1235: hermon_free_qpn ( ibdev, qp );
1236: err_alloc_qpn:
1237: return rc;
1238: }
1239:
1240: /**
1241: * Modify queue pair
1242: *
1243: * @v ibdev Infiniband device
1244: * @v qp Queue pair
1245: * @ret rc Return status code
1246: */
1247: static int hermon_modify_qp ( struct ib_device *ibdev,
1248: struct ib_queue_pair *qp ) {
1249: struct hermon *hermon = ib_get_drvdata ( ibdev );
1250: struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
1251: struct hermonprm_qp_ee_state_transitions qpctx;
1252: int rc;
1253:
1254: /* Transition queue to RTR state, if applicable */
1255: if ( hermon_qp->state < HERMON_QP_ST_RTR ) {
1256: memset ( &qpctx, 0, sizeof ( qpctx ) );
1257: MLX_FILL_2 ( &qpctx, 4,
1258: qpc_eec_data.mtu,
1259: ( ( qp->type == IB_QPT_ETH ) ?
1260: HERMON_MTU_ETH : HERMON_MTU_2048 ),
1261: qpc_eec_data.msg_max, 31 );
1262: MLX_FILL_1 ( &qpctx, 7,
1263: qpc_eec_data.remote_qpn_een, qp->av.qpn );
1264: MLX_FILL_1 ( &qpctx, 9,
1265: qpc_eec_data.primary_address_path.rlid,
1266: qp->av.lid );
1267: MLX_FILL_1 ( &qpctx, 10,
1268: qpc_eec_data.primary_address_path.max_stat_rate,
1269: hermon_rate ( &qp->av ) );
1270: memcpy ( &qpctx.u.dwords[12], &qp->av.gid,
1271: sizeof ( qp->av.gid ) );
1272: MLX_FILL_1 ( &qpctx, 16,
1273: qpc_eec_data.primary_address_path.sched_queue,
1274: hermon_sched_queue ( ibdev, qp ) );
1275: MLX_FILL_1 ( &qpctx, 39,
1276: qpc_eec_data.next_rcv_psn, qp->recv.psn );
1277: if ( ( rc = hermon_cmd_init2rtr_qp ( hermon, qp->qpn,
1278: &qpctx ) ) != 0 ) {
1279: DBGC ( hermon, "Hermon %p QPN %#lx INIT2RTR_QP failed:"
1280: " %s\n", hermon, qp->qpn, strerror ( rc ) );
1281: return rc;
1282: }
1283: hermon_qp->state = HERMON_QP_ST_RTR;
1284: }
1285:
1286: /* Transition queue to RTS state */
1287: if ( hermon_qp->state < HERMON_QP_ST_RTS ) {
1288: memset ( &qpctx, 0, sizeof ( qpctx ) );
1289: MLX_FILL_1 ( &qpctx, 10,
1290: qpc_eec_data.primary_address_path.ack_timeout,
1291: 14 /* 4.096us * 2^(14) = 67ms */ );
1292: MLX_FILL_2 ( &qpctx, 30,
1293: qpc_eec_data.retry_count, HERMON_RETRY_MAX,
1294: qpc_eec_data.rnr_retry, HERMON_RETRY_MAX );
1295: MLX_FILL_1 ( &qpctx, 32,
1296: qpc_eec_data.next_send_psn, qp->send.psn );
1297: if ( ( rc = hermon_cmd_rtr2rts_qp ( hermon, qp->qpn,
1298: &qpctx ) ) != 0 ) {
1299: DBGC ( hermon, "Hermon %p QPN %#lx RTR2RTS_QP failed: "
1300: "%s\n", hermon, qp->qpn, strerror ( rc ) );
1301: return rc;
1302: }
1303: hermon_qp->state = HERMON_QP_ST_RTS;
1304: }
1305:
1306: /* Update parameters in RTS state */
1307: memset ( &qpctx, 0, sizeof ( qpctx ) );
1308: MLX_FILL_1 ( &qpctx, 0, opt_param_mask, HERMON_QP_OPT_PARAM_QKEY );
1309: MLX_FILL_1 ( &qpctx, 44, qpc_eec_data.q_key, qp->qkey );
1310: if ( ( rc = hermon_cmd_rts2rts_qp ( hermon, qp->qpn, &qpctx ) ) != 0 ){
1311: DBGC ( hermon, "Hermon %p QPN %#lx RTS2RTS_QP failed: %s\n",
1312: hermon, qp->qpn, strerror ( rc ) );
1313: return rc;
1314: }
1315:
1316: return 0;
1317: }
1318:
1319: /**
1320: * Destroy queue pair
1321: *
1322: * @v ibdev Infiniband device
1323: * @v qp Queue pair
1324: */
1325: static void hermon_destroy_qp ( struct ib_device *ibdev,
1326: struct ib_queue_pair *qp ) {
1327: struct hermon *hermon = ib_get_drvdata ( ibdev );
1328: struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
1329: int rc;
1330:
1331: /* Take ownership back from hardware */
1332: if ( ( rc = hermon_cmd_2rst_qp ( hermon, qp->qpn ) ) != 0 ) {
1333: DBGC ( hermon, "Hermon %p QPN %#lx FATAL 2RST_QP failed: %s\n",
1334: hermon, qp->qpn, strerror ( rc ) );
1335: /* Leak memory and return; at least we avoid corruption */
1336: return;
1337: }
1338:
1339: /* Free MTT entries */
1340: hermon_free_mtt ( hermon, &hermon_qp->mtt );
1341:
1342: /* Free memory */
1343: free_dma ( hermon_qp->wqe, hermon_qp->wqe_size );
1344: free_dma ( hermon_qp->recv.doorbell,
1345: sizeof ( hermon_qp->recv.doorbell[0] ) );
1346: free ( hermon_qp );
1347:
1348: /* Mark queue number as free */
1349: hermon_free_qpn ( ibdev, qp );
1350:
1351: ib_qp_set_drvdata ( qp, NULL );
1352: }
1353:
1354: /***************************************************************************
1355: *
1356: * Work request operations
1357: *
1358: ***************************************************************************
1359: */
1360:
1361: /**
1362: * Construct UD send work queue entry
1363: *
1364: * @v ibdev Infiniband device
1365: * @v qp Queue pair
1366: * @v av Address vector
1367: * @v iobuf I/O buffer
1368: * @v wqe Send work queue entry
1369: * @ret opcode Control opcode
1370: */
1371: static __attribute__ (( unused )) unsigned int
1372: hermon_fill_nop_send_wqe ( struct ib_device *ibdev __unused,
1373: struct ib_queue_pair *qp __unused,
1374: struct ib_address_vector *av __unused,
1375: struct io_buffer *iobuf __unused,
1376: union hermon_send_wqe *wqe ) {
1377:
1378: MLX_FILL_1 ( &wqe->ctrl, 1, ds, ( sizeof ( wqe->ctrl ) / 16 ) );
1379: MLX_FILL_1 ( &wqe->ctrl, 2, c, 0x03 /* generate completion */ );
1380: return HERMON_OPCODE_NOP;
1381: }
1382:
1383: /**
1384: * Construct UD send work queue entry
1385: *
1386: * @v ibdev Infiniband device
1387: * @v qp Queue pair
1388: * @v av Address vector
1389: * @v iobuf I/O buffer
1390: * @v wqe Send work queue entry
1391: * @ret opcode Control opcode
1392: */
1393: static unsigned int
1394: hermon_fill_ud_send_wqe ( struct ib_device *ibdev,
1395: struct ib_queue_pair *qp __unused,
1396: struct ib_address_vector *av,
1397: struct io_buffer *iobuf,
1398: union hermon_send_wqe *wqe ) {
1399: struct hermon *hermon = ib_get_drvdata ( ibdev );
1400:
1401: MLX_FILL_1 ( &wqe->ud.ctrl, 1, ds,
1402: ( ( offsetof ( typeof ( wqe->ud ), data[1] ) / 16 ) ) );
1403: MLX_FILL_1 ( &wqe->ud.ctrl, 2, c, 0x03 /* generate completion */ );
1404: MLX_FILL_2 ( &wqe->ud.ud, 0,
1405: ud_address_vector.pd, HERMON_GLOBAL_PD,
1406: ud_address_vector.port_number, ibdev->port );
1407: MLX_FILL_2 ( &wqe->ud.ud, 1,
1408: ud_address_vector.rlid, av->lid,
1409: ud_address_vector.g, av->gid_present );
1410: MLX_FILL_1 ( &wqe->ud.ud, 2,
1411: ud_address_vector.max_stat_rate, hermon_rate ( av ) );
1412: MLX_FILL_1 ( &wqe->ud.ud, 3, ud_address_vector.sl, av->sl );
1413: memcpy ( &wqe->ud.ud.u.dwords[4], &av->gid, sizeof ( av->gid ) );
1414: MLX_FILL_1 ( &wqe->ud.ud, 8, destination_qp, av->qpn );
1415: MLX_FILL_1 ( &wqe->ud.ud, 9, q_key, av->qkey );
1416: MLX_FILL_1 ( &wqe->ud.data[0], 0, byte_count, iob_len ( iobuf ) );
1417: MLX_FILL_1 ( &wqe->ud.data[0], 1, l_key, hermon->lkey );
1418: MLX_FILL_H ( &wqe->ud.data[0], 2,
1419: local_address_h, virt_to_bus ( iobuf->data ) );
1420: MLX_FILL_1 ( &wqe->ud.data[0], 3,
1421: local_address_l, virt_to_bus ( iobuf->data ) );
1422: return HERMON_OPCODE_SEND;
1423: }
1424:
1425: /**
1426: * Construct MLX send work queue entry
1427: *
1428: * @v ibdev Infiniband device
1429: * @v qp Queue pair
1430: * @v av Address vector
1431: * @v iobuf I/O buffer
1432: * @v wqe Send work queue entry
1433: * @ret opcode Control opcode
1434: */
1435: static unsigned int
1436: hermon_fill_mlx_send_wqe ( struct ib_device *ibdev,
1437: struct ib_queue_pair *qp,
1438: struct ib_address_vector *av,
1439: struct io_buffer *iobuf,
1440: union hermon_send_wqe *wqe ) {
1441: struct hermon *hermon = ib_get_drvdata ( ibdev );
1442: struct io_buffer headers;
1443:
1444: /* Construct IB headers */
1445: iob_populate ( &headers, &wqe->mlx.headers, 0,
1446: sizeof ( wqe->mlx.headers ) );
1447: iob_reserve ( &headers, sizeof ( wqe->mlx.headers ) );
1448: ib_push ( ibdev, &headers, qp, iob_len ( iobuf ), av );
1449:
1450: /* Fill work queue entry */
1451: MLX_FILL_1 ( &wqe->mlx.ctrl, 1, ds,
1452: ( ( offsetof ( typeof ( wqe->mlx ), data[2] ) / 16 ) ) );
1453: MLX_FILL_5 ( &wqe->mlx.ctrl, 2,
1454: c, 0x03 /* generate completion */,
1455: icrc, 0 /* generate ICRC */,
1456: max_statrate, hermon_rate ( av ),
1457: slr, 0,
1458: v15, ( ( qp->ext_qpn == IB_QPN_SMI ) ? 1 : 0 ) );
1459: MLX_FILL_1 ( &wqe->mlx.ctrl, 3, rlid, av->lid );
1460: MLX_FILL_1 ( &wqe->mlx.data[0], 0,
1461: byte_count, iob_len ( &headers ) );
1462: MLX_FILL_1 ( &wqe->mlx.data[0], 1, l_key, hermon->lkey );
1463: MLX_FILL_H ( &wqe->mlx.data[0], 2,
1464: local_address_h, virt_to_bus ( headers.data ) );
1465: MLX_FILL_1 ( &wqe->mlx.data[0], 3,
1466: local_address_l, virt_to_bus ( headers.data ) );
1467: MLX_FILL_1 ( &wqe->mlx.data[1], 0,
1468: byte_count, ( iob_len ( iobuf ) + 4 /* ICRC */ ) );
1469: MLX_FILL_1 ( &wqe->mlx.data[1], 1, l_key, hermon->lkey );
1470: MLX_FILL_H ( &wqe->mlx.data[1], 2,
1471: local_address_h, virt_to_bus ( iobuf->data ) );
1472: MLX_FILL_1 ( &wqe->mlx.data[1], 3,
1473: local_address_l, virt_to_bus ( iobuf->data ) );
1474: return HERMON_OPCODE_SEND;
1475: }
1476:
1477: /**
1478: * Construct RC send work queue entry
1479: *
1480: * @v ibdev Infiniband device
1481: * @v qp Queue pair
1482: * @v av Address vector
1483: * @v iobuf I/O buffer
1484: * @v wqe Send work queue entry
1485: * @ret opcode Control opcode
1486: */
1487: static unsigned int
1488: hermon_fill_rc_send_wqe ( struct ib_device *ibdev,
1489: struct ib_queue_pair *qp __unused,
1490: struct ib_address_vector *av __unused,
1491: struct io_buffer *iobuf,
1492: union hermon_send_wqe *wqe ) {
1493: struct hermon *hermon = ib_get_drvdata ( ibdev );
1494:
1495: MLX_FILL_1 ( &wqe->rc.ctrl, 1, ds,
1496: ( ( offsetof ( typeof ( wqe->rc ), data[1] ) / 16 ) ) );
1497: MLX_FILL_1 ( &wqe->rc.ctrl, 2, c, 0x03 /* generate completion */ );
1498: MLX_FILL_1 ( &wqe->rc.data[0], 0, byte_count, iob_len ( iobuf ) );
1499: MLX_FILL_1 ( &wqe->rc.data[0], 1, l_key, hermon->lkey );
1500: MLX_FILL_H ( &wqe->rc.data[0], 2,
1501: local_address_h, virt_to_bus ( iobuf->data ) );
1502: MLX_FILL_1 ( &wqe->rc.data[0], 3,
1503: local_address_l, virt_to_bus ( iobuf->data ) );
1504: return HERMON_OPCODE_SEND;
1505: }
1506:
1507: /**
1508: * Construct Ethernet send work queue entry
1509: *
1510: * @v ibdev Infiniband device
1511: * @v qp Queue pair
1512: * @v av Address vector
1513: * @v iobuf I/O buffer
1514: * @v wqe Send work queue entry
1515: * @ret opcode Control opcode
1516: */
1517: static unsigned int
1518: hermon_fill_eth_send_wqe ( struct ib_device *ibdev,
1519: struct ib_queue_pair *qp __unused,
1520: struct ib_address_vector *av __unused,
1521: struct io_buffer *iobuf,
1522: union hermon_send_wqe *wqe ) {
1523: struct hermon *hermon = ib_get_drvdata ( ibdev );
1524:
1525: /* Fill work queue entry */
1526: MLX_FILL_1 ( &wqe->eth.ctrl, 1, ds,
1527: ( ( offsetof ( typeof ( wqe->mlx ), data[1] ) / 16 ) ) );
1528: MLX_FILL_2 ( &wqe->eth.ctrl, 2,
1529: c, 0x03 /* generate completion */,
1530: s, 1 /* inhibit ICRC */ );
1531: MLX_FILL_1 ( &wqe->eth.data[0], 0,
1532: byte_count, iob_len ( iobuf ) );
1533: MLX_FILL_1 ( &wqe->eth.data[0], 1, l_key, hermon->lkey );
1534: MLX_FILL_H ( &wqe->eth.data[0], 2,
1535: local_address_h, virt_to_bus ( iobuf->data ) );
1536: MLX_FILL_1 ( &wqe->eth.data[0], 3,
1537: local_address_l, virt_to_bus ( iobuf->data ) );
1538: return HERMON_OPCODE_SEND;
1539: }
1540:
1541: /** Work queue entry constructors */
1542: static unsigned int
1543: ( * hermon_fill_send_wqe[] ) ( struct ib_device *ibdev,
1544: struct ib_queue_pair *qp,
1545: struct ib_address_vector *av,
1546: struct io_buffer *iobuf,
1547: union hermon_send_wqe *wqe ) = {
1548: [IB_QPT_SMI] = hermon_fill_mlx_send_wqe,
1549: [IB_QPT_GSI] = hermon_fill_mlx_send_wqe,
1550: [IB_QPT_UD] = hermon_fill_ud_send_wqe,
1551: [IB_QPT_RC] = hermon_fill_rc_send_wqe,
1552: [IB_QPT_ETH] = hermon_fill_eth_send_wqe,
1553: };
1554:
1555: /**
1556: * Post send work queue entry
1557: *
1558: * @v ibdev Infiniband device
1559: * @v qp Queue pair
1560: * @v av Address vector
1561: * @v iobuf I/O buffer
1562: * @ret rc Return status code
1563: */
1564: static int hermon_post_send ( struct ib_device *ibdev,
1565: struct ib_queue_pair *qp,
1566: struct ib_address_vector *av,
1567: struct io_buffer *iobuf ) {
1568: struct hermon *hermon = ib_get_drvdata ( ibdev );
1569: struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
1570: struct ib_work_queue *wq = &qp->send;
1571: struct hermon_send_work_queue *hermon_send_wq = &hermon_qp->send;
1572: union hermon_send_wqe *wqe;
1573: union hermonprm_doorbell_register db_reg;
1574: unsigned long wqe_idx_mask;
1575: unsigned long wqe_idx;
1576: unsigned int owner;
1577: unsigned int opcode;
1578:
1579: /* Allocate work queue entry */
1580: wqe_idx = ( wq->next_idx & ( hermon_send_wq->num_wqes - 1 ) );
1581: owner = ( ( wq->next_idx & hermon_send_wq->num_wqes ) ? 1 : 0 );
1582: wqe_idx_mask = ( wq->num_wqes - 1 );
1583: if ( wq->iobufs[ wqe_idx & wqe_idx_mask ] ) {
1584: DBGC ( hermon, "Hermon %p QPN %#lx send queue full",
1585: hermon, qp->qpn );
1586: return -ENOBUFS;
1587: }
1588: wq->iobufs[ wqe_idx & wqe_idx_mask ] = iobuf;
1589: wqe = &hermon_send_wq->wqe[wqe_idx];
1590:
1591: /* Construct work queue entry */
1592: memset ( ( ( ( void * ) wqe ) + 4 /* avoid ctrl.owner */ ), 0,
1593: ( sizeof ( *wqe ) - 4 ) );
1594: assert ( qp->type < ( sizeof ( hermon_fill_send_wqe ) /
1595: sizeof ( hermon_fill_send_wqe[0] ) ) );
1596: assert ( hermon_fill_send_wqe[qp->type] != NULL );
1597: opcode = hermon_fill_send_wqe[qp->type] ( ibdev, qp, av, iobuf, wqe );
1598: barrier();
1599: MLX_FILL_2 ( &wqe->ctrl, 0,
1600: opcode, opcode,
1601: owner, owner );
1602: DBGCP ( hermon, "Hermon %p QPN %#lx posting send WQE %#lx:\n",
1603: hermon, qp->qpn, wqe_idx );
1604: DBGCP_HDA ( hermon, virt_to_phys ( wqe ), wqe, sizeof ( *wqe ) );
1605:
1606: /* Ring doorbell register */
1607: MLX_FILL_1 ( &db_reg.send, 0, qn, qp->qpn );
1608: barrier();
1609: writel ( db_reg.dword[0], hermon_send_wq->doorbell );
1610:
1611: /* Update work queue's index */
1612: wq->next_idx++;
1613:
1614: return 0;
1615: }
1616:
1617: /**
1618: * Post receive work queue entry
1619: *
1620: * @v ibdev Infiniband device
1621: * @v qp Queue pair
1622: * @v iobuf I/O buffer
1623: * @ret rc Return status code
1624: */
1625: static int hermon_post_recv ( struct ib_device *ibdev,
1626: struct ib_queue_pair *qp,
1627: struct io_buffer *iobuf ) {
1628: struct hermon *hermon = ib_get_drvdata ( ibdev );
1629: struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
1630: struct ib_work_queue *wq = &qp->recv;
1631: struct hermon_recv_work_queue *hermon_recv_wq = &hermon_qp->recv;
1632: struct hermonprm_recv_wqe *wqe;
1633: unsigned int wqe_idx_mask;
1634:
1635: /* Allocate work queue entry */
1636: wqe_idx_mask = ( wq->num_wqes - 1 );
1637: if ( wq->iobufs[wq->next_idx & wqe_idx_mask] ) {
1638: DBGC ( hermon, "Hermon %p QPN %#lx receive queue full",
1639: hermon, qp->qpn );
1640: return -ENOBUFS;
1641: }
1642: wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
1643: wqe = &hermon_recv_wq->wqe[wq->next_idx & wqe_idx_mask].recv;
1644:
1645: /* Construct work queue entry */
1646: MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_tailroom ( iobuf ) );
1647: MLX_FILL_1 ( &wqe->data[0], 1, l_key, hermon->lkey );
1648: MLX_FILL_H ( &wqe->data[0], 2,
1649: local_address_h, virt_to_bus ( iobuf->data ) );
1650: MLX_FILL_1 ( &wqe->data[0], 3,
1651: local_address_l, virt_to_bus ( iobuf->data ) );
1652:
1653: /* Update work queue's index */
1654: wq->next_idx++;
1655:
1656: /* Update doorbell record */
1657: barrier();
1658: MLX_FILL_1 ( hermon_recv_wq->doorbell, 0, receive_wqe_counter,
1659: ( wq->next_idx & 0xffff ) );
1660:
1661: return 0;
1662: }
1663:
1664: /**
1665: * Handle completion
1666: *
1667: * @v ibdev Infiniband device
1668: * @v cq Completion queue
1669: * @v cqe Hardware completion queue entry
1670: * @ret rc Return status code
1671: */
1672: static int hermon_complete ( struct ib_device *ibdev,
1673: struct ib_completion_queue *cq,
1674: union hermonprm_completion_entry *cqe ) {
1675: struct hermon *hermon = ib_get_drvdata ( ibdev );
1676: struct ib_work_queue *wq;
1677: struct ib_queue_pair *qp;
1678: struct io_buffer *iobuf;
1679: struct ib_address_vector recv_av;
1680: struct ib_global_route_header *grh;
1681: struct ib_address_vector *av;
1682: unsigned int opcode;
1683: unsigned long qpn;
1684: int is_send;
1685: unsigned long wqe_idx;
1686: unsigned long wqe_idx_mask;
1687: size_t len;
1688: int rc = 0;
1689:
1690: /* Parse completion */
1691: qpn = MLX_GET ( &cqe->normal, qpn );
1692: is_send = MLX_GET ( &cqe->normal, s_r );
1693: opcode = MLX_GET ( &cqe->normal, opcode );
1694: if ( opcode >= HERMON_OPCODE_RECV_ERROR ) {
1695: /* "s" field is not valid for error opcodes */
1696: is_send = ( opcode == HERMON_OPCODE_SEND_ERROR );
1697: DBGC ( hermon, "Hermon %p CQN %#lx syndrome %x vendor %x\n",
1698: hermon, cq->cqn, MLX_GET ( &cqe->error, syndrome ),
1699: MLX_GET ( &cqe->error, vendor_error_syndrome ) );
1700: rc = -EIO;
1701: /* Don't return immediately; propagate error to completer */
1702: }
1703:
1704: /* Identify work queue */
1705: wq = ib_find_wq ( cq, qpn, is_send );
1706: if ( ! wq ) {
1707: DBGC ( hermon, "Hermon %p CQN %#lx unknown %s QPN %#lx\n",
1708: hermon, cq->cqn, ( is_send ? "send" : "recv" ), qpn );
1709: return -EIO;
1710: }
1711: qp = wq->qp;
1712:
1713: /* Identify work queue entry */
1714: wqe_idx = MLX_GET ( &cqe->normal, wqe_counter );
1715: wqe_idx_mask = ( wq->num_wqes - 1 );
1716: DBGCP ( hermon, "Hermon %p CQN %#lx QPN %#lx %s WQE %#lx completed:\n",
1717: hermon, cq->cqn, qp->qpn, ( is_send ? "send" : "recv" ),
1718: wqe_idx );
1719: DBGCP_HDA ( hermon, virt_to_phys ( cqe ), cqe, sizeof ( *cqe ) );
1720:
1721: /* Identify I/O buffer */
1722: iobuf = wq->iobufs[ wqe_idx & wqe_idx_mask ];
1723: if ( ! iobuf ) {
1724: DBGC ( hermon, "Hermon %p CQN %#lx QPN %#lx empty %s WQE "
1725: "%#lx\n", hermon, cq->cqn, qp->qpn,
1726: ( is_send ? "send" : "recv" ), wqe_idx );
1727: return -EIO;
1728: }
1729: wq->iobufs[ wqe_idx & wqe_idx_mask ] = NULL;
1730:
1731: if ( is_send ) {
1732: /* Hand off to completion handler */
1733: ib_complete_send ( ibdev, qp, iobuf, rc );
1734: } else {
1735: /* Set received length */
1736: len = MLX_GET ( &cqe->normal, byte_cnt );
1737: assert ( len <= iob_tailroom ( iobuf ) );
1738: iob_put ( iobuf, len );
1739: memset ( &recv_av, 0, sizeof ( recv_av ) );
1740: switch ( qp->type ) {
1741: case IB_QPT_SMI:
1742: case IB_QPT_GSI:
1743: case IB_QPT_UD:
1744: assert ( iob_len ( iobuf ) >= sizeof ( *grh ) );
1745: grh = iobuf->data;
1746: iob_pull ( iobuf, sizeof ( *grh ) );
1747: /* Construct address vector */
1748: av = &recv_av;
1749: av->qpn = MLX_GET ( &cqe->normal, srq_rqpn );
1750: av->lid = MLX_GET ( &cqe->normal, slid_smac47_32 );
1751: av->sl = MLX_GET ( &cqe->normal, sl );
1752: av->gid_present = MLX_GET ( &cqe->normal, g );
1753: memcpy ( &av->gid, &grh->sgid, sizeof ( av->gid ) );
1754: break;
1755: case IB_QPT_RC:
1756: av = &qp->av;
1757: break;
1758: case IB_QPT_ETH:
1759: /* Construct address vector */
1760: av = &recv_av;
1761: av->vlan_present = MLX_GET ( &cqe->normal, vlan );
1762: av->vlan = MLX_GET ( &cqe->normal, vid );
1763: break;
1764: default:
1765: assert ( 0 );
1766: return -EINVAL;
1767: }
1768: /* Hand off to completion handler */
1769: ib_complete_recv ( ibdev, qp, av, iobuf, rc );
1770: }
1771:
1772: return rc;
1773: }
1774:
1775: /**
1776: * Poll completion queue
1777: *
1778: * @v ibdev Infiniband device
1779: * @v cq Completion queue
1780: */
1781: static void hermon_poll_cq ( struct ib_device *ibdev,
1782: struct ib_completion_queue *cq ) {
1783: struct hermon *hermon = ib_get_drvdata ( ibdev );
1784: struct hermon_completion_queue *hermon_cq = ib_cq_get_drvdata ( cq );
1785: union hermonprm_completion_entry *cqe;
1786: unsigned int cqe_idx_mask;
1787: int rc;
1788:
1789: while ( 1 ) {
1790: /* Look for completion entry */
1791: cqe_idx_mask = ( cq->num_cqes - 1 );
1792: cqe = &hermon_cq->cqe[cq->next_idx & cqe_idx_mask];
1793: if ( MLX_GET ( &cqe->normal, owner ) ^
1794: ( ( cq->next_idx & cq->num_cqes ) ? 1 : 0 ) ) {
1795: /* Entry still owned by hardware; end of poll */
1796: break;
1797: }
1798:
1799: /* Handle completion */
1800: if ( ( rc = hermon_complete ( ibdev, cq, cqe ) ) != 0 ) {
1801: DBGC ( hermon, "Hermon %p CQN %#lx failed to complete:"
1802: " %s\n", hermon, cq->cqn, strerror ( rc ) );
1803: DBGC_HDA ( hermon, virt_to_phys ( cqe ),
1804: cqe, sizeof ( *cqe ) );
1805: }
1806:
1807: /* Update completion queue's index */
1808: cq->next_idx++;
1809:
1810: /* Update doorbell record */
1811: MLX_FILL_1 ( hermon_cq->doorbell, 0, update_ci,
1812: ( cq->next_idx & 0x00ffffffUL ) );
1813: }
1814: }
1815:
1816: /***************************************************************************
1817: *
1818: * Event queues
1819: *
1820: ***************************************************************************
1821: */
1822:
1823: /**
1824: * Create event queue
1825: *
1826: * @v hermon Hermon device
1827: * @ret rc Return status code
1828: */
1829: static int hermon_create_eq ( struct hermon *hermon ) {
1830: struct hermon_event_queue *hermon_eq = &hermon->eq;
1831: struct hermonprm_eqc eqctx;
1832: struct hermonprm_event_mask mask;
1833: unsigned int i;
1834: int rc;
1835:
1836: /* Select event queue number */
1837: hermon_eq->eqn = ( 4 * hermon->cap.reserved_uars );
1838: if ( hermon_eq->eqn < hermon->cap.reserved_eqs )
1839: hermon_eq->eqn = hermon->cap.reserved_eqs;
1840:
1841: /* Calculate doorbell address */
1842: hermon_eq->doorbell =
1843: ( hermon->uar + HERMON_DB_EQ_OFFSET ( hermon_eq->eqn ) );
1844:
1845: /* Allocate event queue itself */
1846: hermon_eq->eqe_size =
1847: ( HERMON_NUM_EQES * sizeof ( hermon_eq->eqe[0] ) );
1848: hermon_eq->eqe = malloc_dma ( hermon_eq->eqe_size,
1849: sizeof ( hermon_eq->eqe[0] ) );
1850: if ( ! hermon_eq->eqe ) {
1851: rc = -ENOMEM;
1852: goto err_eqe;
1853: }
1854: memset ( hermon_eq->eqe, 0, hermon_eq->eqe_size );
1855: for ( i = 0 ; i < HERMON_NUM_EQES ; i++ ) {
1856: MLX_FILL_1 ( &hermon_eq->eqe[i].generic, 7, owner, 1 );
1857: }
1858: barrier();
1859:
1860: /* Allocate MTT entries */
1861: if ( ( rc = hermon_alloc_mtt ( hermon, hermon_eq->eqe,
1862: hermon_eq->eqe_size,
1863: &hermon_eq->mtt ) ) != 0 )
1864: goto err_alloc_mtt;
1865:
1866: /* Hand queue over to hardware */
1867: memset ( &eqctx, 0, sizeof ( eqctx ) );
1868: MLX_FILL_2 ( &eqctx, 0,
1869: st, 0xa /* "Fired" */,
1870: oi, 1 );
1871: MLX_FILL_1 ( &eqctx, 2,
1872: page_offset, ( hermon_eq->mtt.page_offset >> 5 ) );
1873: MLX_FILL_1 ( &eqctx, 3, log_eq_size, fls ( HERMON_NUM_EQES - 1 ) );
1874: MLX_FILL_H ( &eqctx, 6, mtt_base_addr_h,
1875: hermon_eq->mtt.mtt_base_addr );
1876: MLX_FILL_1 ( &eqctx, 7, mtt_base_addr_l,
1877: ( hermon_eq->mtt.mtt_base_addr >> 3 ) );
1878: if ( ( rc = hermon_cmd_sw2hw_eq ( hermon, hermon_eq->eqn,
1879: &eqctx ) ) != 0 ) {
1880: DBGC ( hermon, "Hermon %p EQN %#lx SW2HW_EQ failed: %s\n",
1881: hermon, hermon_eq->eqn, strerror ( rc ) );
1882: goto err_sw2hw_eq;
1883: }
1884:
1885: /* Map all events to this event queue */
1886: memset ( &mask, 0xff, sizeof ( mask ) );
1887: if ( ( rc = hermon_cmd_map_eq ( hermon,
1888: ( HERMON_MAP_EQ | hermon_eq->eqn ),
1889: &mask ) ) != 0 ) {
1890: DBGC ( hermon, "Hermon %p EQN %#lx MAP_EQ failed: %s\n",
1891: hermon, hermon_eq->eqn, strerror ( rc ) );
1892: goto err_map_eq;
1893: }
1894:
1895: DBGC ( hermon, "Hermon %p EQN %#lx ring [%08lx,%08lx), doorbell "
1896: "%08lx\n", hermon, hermon_eq->eqn,
1897: virt_to_phys ( hermon_eq->eqe ),
1898: ( virt_to_phys ( hermon_eq->eqe ) + hermon_eq->eqe_size ),
1899: virt_to_phys ( hermon_eq->doorbell ) );
1900: return 0;
1901:
1902: err_map_eq:
1903: hermon_cmd_hw2sw_eq ( hermon, hermon_eq->eqn, &eqctx );
1904: err_sw2hw_eq:
1905: hermon_free_mtt ( hermon, &hermon_eq->mtt );
1906: err_alloc_mtt:
1907: free_dma ( hermon_eq->eqe, hermon_eq->eqe_size );
1908: err_eqe:
1909: memset ( hermon_eq, 0, sizeof ( *hermon_eq ) );
1910: return rc;
1911: }
1912:
1913: /**
1914: * Destroy event queue
1915: *
1916: * @v hermon Hermon device
1917: */
1918: static void hermon_destroy_eq ( struct hermon *hermon ) {
1919: struct hermon_event_queue *hermon_eq = &hermon->eq;
1920: struct hermonprm_eqc eqctx;
1921: struct hermonprm_event_mask mask;
1922: int rc;
1923:
1924: /* Unmap events from event queue */
1925: memset ( &mask, 0xff, sizeof ( mask ) );
1926: if ( ( rc = hermon_cmd_map_eq ( hermon,
1927: ( HERMON_UNMAP_EQ | hermon_eq->eqn ),
1928: &mask ) ) != 0 ) {
1929: DBGC ( hermon, "Hermon %p EQN %#lx FATAL MAP_EQ failed to "
1930: "unmap: %s\n", hermon, hermon_eq->eqn, strerror ( rc ) );
1931: /* Continue; HCA may die but system should survive */
1932: }
1933:
1934: /* Take ownership back from hardware */
1935: if ( ( rc = hermon_cmd_hw2sw_eq ( hermon, hermon_eq->eqn,
1936: &eqctx ) ) != 0 ) {
1937: DBGC ( hermon, "Hermon %p EQN %#lx FATAL HW2SW_EQ failed: %s\n",
1938: hermon, hermon_eq->eqn, strerror ( rc ) );
1939: /* Leak memory and return; at least we avoid corruption */
1940: return;
1941: }
1942:
1943: /* Free MTT entries */
1944: hermon_free_mtt ( hermon, &hermon_eq->mtt );
1945:
1946: /* Free memory */
1947: free_dma ( hermon_eq->eqe, hermon_eq->eqe_size );
1948: memset ( hermon_eq, 0, sizeof ( *hermon_eq ) );
1949: }
1950:
1951: /**
1952: * Handle port state event
1953: *
1954: * @v hermon Hermon device
1955: * @v eqe Port state change event queue entry
1956: */
1957: static void hermon_event_port_state_change ( struct hermon *hermon,
1958: union hermonprm_event_entry *eqe){
1959: unsigned int port;
1960: int link_up;
1961:
1962: /* Get port and link status */
1963: port = ( MLX_GET ( &eqe->port_state_change, data.p ) - 1 );
1964: link_up = ( MLX_GET ( &eqe->generic, event_sub_type ) & 0x04 );
1965: DBGC ( hermon, "Hermon %p port %d link %s\n", hermon, ( port + 1 ),
1966: ( link_up ? "up" : "down" ) );
1967:
1968: /* Sanity check */
1969: if ( port >= hermon->cap.num_ports ) {
1970: DBGC ( hermon, "Hermon %p port %d does not exist!\n",
1971: hermon, ( port + 1 ) );
1972: return;
1973: }
1974:
1975: /* Notify device of port state change */
1976: hermon->port[port].type->state_change ( hermon, &hermon->port[port],
1977: link_up );
1978: }
1979:
1980: /**
1981: * Poll event queue
1982: *
1983: * @v ibdev Infiniband device
1984: */
1985: static void hermon_poll_eq ( struct ib_device *ibdev ) {
1986: struct hermon *hermon = ib_get_drvdata ( ibdev );
1987: struct hermon_event_queue *hermon_eq = &hermon->eq;
1988: union hermonprm_event_entry *eqe;
1989: union hermonprm_doorbell_register db_reg;
1990: unsigned int eqe_idx_mask;
1991: unsigned int event_type;
1992:
1993: /* No event is generated upon reaching INIT, so we must poll
1994: * separately for link state changes while we remain DOWN.
1995: */
1996: if ( ib_is_open ( ibdev ) &&
1997: ( ibdev->port_state == IB_PORT_STATE_DOWN ) ) {
1998: ib_smc_update ( ibdev, hermon_mad );
1999: }
2000:
2001: /* Poll event queue */
2002: while ( 1 ) {
2003: /* Look for event entry */
2004: eqe_idx_mask = ( HERMON_NUM_EQES - 1 );
2005: eqe = &hermon_eq->eqe[hermon_eq->next_idx & eqe_idx_mask];
2006: if ( MLX_GET ( &eqe->generic, owner ) ^
2007: ( ( hermon_eq->next_idx & HERMON_NUM_EQES ) ? 1 : 0 ) ) {
2008: /* Entry still owned by hardware; end of poll */
2009: break;
2010: }
2011: DBGCP ( hermon, "Hermon %p EQN %#lx event:\n",
2012: hermon, hermon_eq->eqn );
2013: DBGCP_HDA ( hermon, virt_to_phys ( eqe ),
2014: eqe, sizeof ( *eqe ) );
2015:
2016: /* Handle event */
2017: event_type = MLX_GET ( &eqe->generic, event_type );
2018: switch ( event_type ) {
2019: case HERMON_EV_PORT_STATE_CHANGE:
2020: hermon_event_port_state_change ( hermon, eqe );
2021: break;
2022: default:
2023: DBGC ( hermon, "Hermon %p EQN %#lx unrecognised event "
2024: "type %#x:\n",
2025: hermon, hermon_eq->eqn, event_type );
2026: DBGC_HDA ( hermon, virt_to_phys ( eqe ),
2027: eqe, sizeof ( *eqe ) );
2028: break;
2029: }
2030:
2031: /* Update event queue's index */
2032: hermon_eq->next_idx++;
2033:
2034: /* Ring doorbell */
2035: MLX_FILL_1 ( &db_reg.event, 0,
2036: ci, ( hermon_eq->next_idx & 0x00ffffffUL ) );
2037: writel ( db_reg.dword[0], hermon_eq->doorbell );
2038: }
2039: }
2040:
2041: /***************************************************************************
2042: *
2043: * Infiniband link-layer operations
2044: *
2045: ***************************************************************************
2046: */
2047:
2048: /**
2049: * Initialise Infiniband link
2050: *
2051: * @v ibdev Infiniband device
2052: * @ret rc Return status code
2053: */
2054: static int hermon_open ( struct ib_device *ibdev ) {
2055: struct hermon *hermon = ib_get_drvdata ( ibdev );
2056: union hermonprm_set_port set_port;
2057: int rc;
2058:
2059: /* Set port parameters */
2060: memset ( &set_port, 0, sizeof ( set_port ) );
2061: MLX_FILL_8 ( &set_port.ib, 0,
2062: mmc, 1,
2063: mvc, 1,
2064: mp, 1,
2065: mg, 1,
2066: mtu_cap, IB_MTU_2048,
2067: vl_cap, IB_VL_0,
2068: rcm, 1,
2069: lss, 1 );
2070: MLX_FILL_2 ( &set_port.ib, 10,
2071: max_pkey, 1,
2072: max_gid, 1 );
2073: MLX_FILL_1 ( &set_port.ib, 28,
2074: link_speed_supported, 1 );
2075: if ( ( rc = hermon_cmd_set_port ( hermon, 0, ibdev->port,
2076: &set_port ) ) != 0 ) {
2077: DBGC ( hermon, "Hermon %p port %d could not set port: %s\n",
2078: hermon, ibdev->port, strerror ( rc ) );
2079: return rc;
2080: }
2081:
2082: /* Initialise port */
2083: if ( ( rc = hermon_cmd_init_port ( hermon, ibdev->port ) ) != 0 ) {
2084: DBGC ( hermon, "Hermon %p port %d could not initialise port: "
2085: "%s\n", hermon, ibdev->port, strerror ( rc ) );
2086: return rc;
2087: }
2088:
2089: /* Update MAD parameters */
2090: ib_smc_update ( ibdev, hermon_mad );
2091:
2092: return 0;
2093: }
2094:
2095: /**
2096: * Close Infiniband link
2097: *
2098: * @v ibdev Infiniband device
2099: */
2100: static void hermon_close ( struct ib_device *ibdev ) {
2101: struct hermon *hermon = ib_get_drvdata ( ibdev );
2102: int rc;
2103:
2104: if ( ( rc = hermon_cmd_close_port ( hermon, ibdev->port ) ) != 0 ) {
2105: DBGC ( hermon, "Hermon %p port %d could not close port: %s\n",
2106: hermon, ibdev->port, strerror ( rc ) );
2107: /* Nothing we can do about this */
2108: }
2109: }
2110:
2111: /**
2112: * Inform embedded subnet management agent of a received MAD
2113: *
2114: * @v ibdev Infiniband device
2115: * @v mad MAD
2116: * @ret rc Return status code
2117: */
2118: static int hermon_inform_sma ( struct ib_device *ibdev,
2119: union ib_mad *mad ) {
2120: int rc;
2121:
2122: /* Send the MAD to the embedded SMA */
2123: if ( ( rc = hermon_mad ( ibdev, mad ) ) != 0 )
2124: return rc;
2125:
2126: /* Update parameters held in software */
2127: ib_smc_update ( ibdev, hermon_mad );
2128:
2129: return 0;
2130: }
2131:
2132: /***************************************************************************
2133: *
2134: * Multicast group operations
2135: *
2136: ***************************************************************************
2137: */
2138:
2139: /**
2140: * Attach to multicast group
2141: *
2142: * @v ibdev Infiniband device
2143: * @v qp Queue pair
2144: * @v gid Multicast GID
2145: * @ret rc Return status code
2146: */
2147: static int hermon_mcast_attach ( struct ib_device *ibdev,
2148: struct ib_queue_pair *qp,
2149: union ib_gid *gid ) {
2150: struct hermon *hermon = ib_get_drvdata ( ibdev );
2151: struct hermonprm_mgm_hash hash;
2152: struct hermonprm_mcg_entry mcg;
2153: unsigned int index;
2154: int rc;
2155:
2156: /* Generate hash table index */
2157: if ( ( rc = hermon_cmd_mgid_hash ( hermon, gid, &hash ) ) != 0 ) {
2158: DBGC ( hermon, "Hermon %p could not hash GID: %s\n",
2159: hermon, strerror ( rc ) );
2160: return rc;
2161: }
2162: index = MLX_GET ( &hash, hash );
2163:
2164: /* Check for existing hash table entry */
2165: if ( ( rc = hermon_cmd_read_mcg ( hermon, index, &mcg ) ) != 0 ) {
2166: DBGC ( hermon, "Hermon %p could not read MCG %#x: %s\n",
2167: hermon, index, strerror ( rc ) );
2168: return rc;
2169: }
2170: if ( MLX_GET ( &mcg, hdr.members_count ) != 0 ) {
2171: /* FIXME: this implementation allows only a single QP
2172: * per multicast group, and doesn't handle hash
2173: * collisions. Sufficient for IPoIB but may need to
2174: * be extended in future.
2175: */
2176: DBGC ( hermon, "Hermon %p MGID index %#x already in use\n",
2177: hermon, index );
2178: return -EBUSY;
2179: }
2180:
2181: /* Update hash table entry */
2182: MLX_FILL_1 ( &mcg, 1, hdr.members_count, 1 );
2183: MLX_FILL_1 ( &mcg, 8, qp[0].qpn, qp->qpn );
2184: memcpy ( &mcg.u.dwords[4], gid, sizeof ( *gid ) );
2185: if ( ( rc = hermon_cmd_write_mcg ( hermon, index, &mcg ) ) != 0 ) {
2186: DBGC ( hermon, "Hermon %p could not write MCG %#x: %s\n",
2187: hermon, index, strerror ( rc ) );
2188: return rc;
2189: }
2190:
2191: return 0;
2192: }
2193:
2194: /**
2195: * Detach from multicast group
2196: *
2197: * @v ibdev Infiniband device
2198: * @v qp Queue pair
2199: * @v gid Multicast GID
2200: */
2201: static void hermon_mcast_detach ( struct ib_device *ibdev,
2202: struct ib_queue_pair *qp __unused,
2203: union ib_gid *gid ) {
2204: struct hermon *hermon = ib_get_drvdata ( ibdev );
2205: struct hermonprm_mgm_hash hash;
2206: struct hermonprm_mcg_entry mcg;
2207: unsigned int index;
2208: int rc;
2209:
2210: /* Generate hash table index */
2211: if ( ( rc = hermon_cmd_mgid_hash ( hermon, gid, &hash ) ) != 0 ) {
2212: DBGC ( hermon, "Hermon %p could not hash GID: %s\n",
2213: hermon, strerror ( rc ) );
2214: return;
2215: }
2216: index = MLX_GET ( &hash, hash );
2217:
2218: /* Clear hash table entry */
2219: memset ( &mcg, 0, sizeof ( mcg ) );
2220: if ( ( rc = hermon_cmd_write_mcg ( hermon, index, &mcg ) ) != 0 ) {
2221: DBGC ( hermon, "Hermon %p could not write MCG %#x: %s\n",
2222: hermon, index, strerror ( rc ) );
2223: return;
2224: }
2225: }
2226:
2227: /** Hermon Infiniband operations */
2228: static struct ib_device_operations hermon_ib_operations = {
2229: .create_cq = hermon_create_cq,
2230: .destroy_cq = hermon_destroy_cq,
2231: .create_qp = hermon_create_qp,
2232: .modify_qp = hermon_modify_qp,
2233: .destroy_qp = hermon_destroy_qp,
2234: .post_send = hermon_post_send,
2235: .post_recv = hermon_post_recv,
2236: .poll_cq = hermon_poll_cq,
2237: .poll_eq = hermon_poll_eq,
2238: .open = hermon_open,
2239: .close = hermon_close,
2240: .mcast_attach = hermon_mcast_attach,
2241: .mcast_detach = hermon_mcast_detach,
2242: .set_port_info = hermon_inform_sma,
2243: .set_pkey_table = hermon_inform_sma,
2244: };
2245:
2246: /**
2247: * Register Hermon Infiniband device
2248: *
2249: * @v hermon Hermon device
2250: * @v port Hermon port
2251: * @ret rc Return status code
2252: */
2253: static int hermon_register_ibdev ( struct hermon *hermon,
2254: struct hermon_port *port ) {
2255: struct ib_device *ibdev = port->ibdev;
2256: int rc;
2257:
2258: /* Initialise parameters using SMC */
2259: ib_smc_init ( ibdev, hermon_mad );
2260:
2261: /* Register Infiniband device */
2262: if ( ( rc = register_ibdev ( ibdev ) ) != 0 ) {
2263: DBGC ( hermon, "Hermon %p port %d could not register IB "
2264: "device: %s\n", hermon, ibdev->port, strerror ( rc ) );
2265: return rc;
2266: }
2267:
2268: return 0;
2269: }
2270:
2271: /**
2272: * Handle Hermon Infiniband device port state change
2273: *
2274: * @v hermon Hermon device
2275: * @v port Hermon port
2276: * @v link_up Link is up
2277: */
2278: static void hermon_state_change_ibdev ( struct hermon *hermon __unused,
2279: struct hermon_port *port,
2280: int link_up __unused ) {
2281: struct ib_device *ibdev = port->ibdev;
2282:
2283: /* Update MAD parameters */
2284: ib_smc_update ( ibdev, hermon_mad );
2285: }
2286:
2287: /**
2288: * Unregister Hermon Infiniband device
2289: *
2290: * @v hermon Hermon device
2291: * @v port Hermon port
2292: */
2293: static void hermon_unregister_ibdev ( struct hermon *hermon __unused,
2294: struct hermon_port *port ) {
2295: struct ib_device *ibdev = port->ibdev;
2296:
2297: unregister_ibdev ( ibdev );
2298: }
2299:
2300: /** Hermon Infiniband port type */
2301: static struct hermon_port_type hermon_port_type_ib = {
2302: .register_dev = hermon_register_ibdev,
2303: .state_change = hermon_state_change_ibdev,
2304: .unregister_dev = hermon_unregister_ibdev,
2305: };
2306:
2307: /***************************************************************************
2308: *
2309: * Ethernet operation
2310: *
2311: ***************************************************************************
2312: */
2313:
2314: /** Number of Hermon Ethernet send work queue entries */
2315: #define HERMON_ETH_NUM_SEND_WQES 2
2316:
2317: /** Number of Hermon Ethernet receive work queue entries */
2318: #define HERMON_ETH_NUM_RECV_WQES 4
2319:
2320: /** Number of Hermon Ethernet completion entries */
2321: #define HERMON_ETH_NUM_CQES 8
2322:
2323: /**
2324: * Transmit packet via Hermon Ethernet device
2325: *
2326: * @v netdev Network device
2327: * @v iobuf I/O buffer
2328: * @ret rc Return status code
2329: */
2330: static int hermon_eth_transmit ( struct net_device *netdev,
2331: struct io_buffer *iobuf ) {
2332: struct hermon_port *port = netdev->priv;
2333: struct ib_device *ibdev = port->ibdev;
2334: struct hermon *hermon = ib_get_drvdata ( ibdev );
2335: int rc;
2336:
2337: /* Transmit packet */
2338: if ( ( rc = ib_post_send ( ibdev, port->eth_qp, NULL,
2339: iobuf ) ) != 0 ) {
2340: DBGC ( hermon, "Hermon %p port %d could not transmit: %s\n",
2341: hermon, ibdev->port, strerror ( rc ) );
2342: return rc;
2343: }
2344:
2345: return 0;
2346: }
2347:
2348: /**
2349: * Handle Hermon Ethernet device send completion
2350: *
2351: * @v ibdev Infiniband device
2352: * @v qp Queue pair
2353: * @v iobuf I/O buffer
2354: * @v rc Completion status code
2355: */
2356: static void hermon_eth_complete_send ( struct ib_device *ibdev __unused,
2357: struct ib_queue_pair *qp,
2358: struct io_buffer *iobuf, int rc ) {
2359: struct net_device *netdev = ib_qp_get_ownerdata ( qp );
2360:
2361: netdev_tx_complete_err ( netdev, iobuf, rc );
2362: }
2363:
2364: /**
2365: * Handle Hermon Ethernet device receive completion
2366: *
2367: * @v ibdev Infiniband device
2368: * @v qp Queue pair
2369: * @v av Address vector, or NULL
2370: * @v iobuf I/O buffer
2371: * @v rc Completion status code
2372: */
2373: static void hermon_eth_complete_recv ( struct ib_device *ibdev __unused,
2374: struct ib_queue_pair *qp,
2375: struct ib_address_vector *av,
2376: struct io_buffer *iobuf, int rc ) {
2377: struct net_device *netdev = ib_qp_get_ownerdata ( qp );
2378: struct net_device *vlan;
2379:
2380: /* Find VLAN device, if applicable */
2381: if ( av->vlan_present ) {
2382: if ( ( vlan = vlan_find ( netdev, av->vlan ) ) != NULL ) {
2383: netdev = vlan;
2384: } else if ( rc == 0 ) {
2385: rc = -ENODEV;
2386: }
2387: }
2388:
2389: /* Hand off to network layer */
2390: if ( rc == 0 ) {
2391: netdev_rx ( netdev, iobuf );
2392: } else {
2393: netdev_rx_err ( netdev, iobuf, rc );
2394: }
2395: }
2396:
2397: /** Hermon Ethernet device completion operations */
2398: static struct ib_completion_queue_operations hermon_eth_cq_op = {
2399: .complete_send = hermon_eth_complete_send,
2400: .complete_recv = hermon_eth_complete_recv,
2401: };
2402:
2403: /**
2404: * Poll Hermon Ethernet device
2405: *
2406: * @v netdev Network device
2407: */
2408: static void hermon_eth_poll ( struct net_device *netdev ) {
2409: struct hermon_port *port = netdev->priv;
2410: struct ib_device *ibdev = port->ibdev;
2411:
2412: ib_poll_eq ( ibdev );
2413: }
2414:
2415: /**
2416: * Open Hermon Ethernet device
2417: *
2418: * @v netdev Network device
2419: * @ret rc Return status code
2420: */
2421: static int hermon_eth_open ( struct net_device *netdev ) {
2422: struct hermon_port *port = netdev->priv;
2423: struct ib_device *ibdev = port->ibdev;
2424: struct hermon *hermon = ib_get_drvdata ( ibdev );
2425: union hermonprm_set_port set_port;
2426: int rc;
2427:
2428: /* Allocate completion queue */
2429: port->eth_cq = ib_create_cq ( ibdev, HERMON_ETH_NUM_CQES,
2430: &hermon_eth_cq_op );
2431: if ( ! port->eth_cq ) {
2432: DBGC ( hermon, "Hermon %p port %d could not create completion "
2433: "queue\n", hermon, ibdev->port );
2434: rc = -ENOMEM;
2435: goto err_create_cq;
2436: }
2437:
2438: /* Allocate queue pair */
2439: port->eth_qp = ib_create_qp ( ibdev, IB_QPT_ETH,
2440: HERMON_ETH_NUM_SEND_WQES, port->eth_cq,
2441: HERMON_ETH_NUM_RECV_WQES, port->eth_cq );
2442: if ( ! port->eth_qp ) {
2443: DBGC ( hermon, "Hermon %p port %d could not create queue "
2444: "pair\n", hermon, ibdev->port );
2445: rc = -ENOMEM;
2446: goto err_create_qp;
2447: }
2448: ib_qp_set_ownerdata ( port->eth_qp, netdev );
2449:
2450: /* Activate queue pair */
2451: if ( ( rc = ib_modify_qp ( ibdev, port->eth_qp ) ) != 0 ) {
2452: DBGC ( hermon, "Hermon %p port %d could not modify queue "
2453: "pair: %s\n", hermon, ibdev->port, strerror ( rc ) );
2454: goto err_modify_qp;
2455: }
2456:
2457: /* Fill receive rings */
2458: ib_refill_recv ( ibdev, port->eth_qp );
2459:
2460: /* Set port general parameters */
2461: memset ( &set_port, 0, sizeof ( set_port ) );
2462: MLX_FILL_3 ( &set_port.general, 0,
2463: v_mtu, 1,
2464: v_pprx, 1,
2465: v_pptx, 1 );
2466: MLX_FILL_1 ( &set_port.general, 1,
2467: mtu, ( ETH_FRAME_LEN + 40 /* Used by card */ ) );
2468: MLX_FILL_1 ( &set_port.general, 2,
2469: pfctx, ( 1 << FCOE_VLAN_PRIORITY ) );
2470: MLX_FILL_1 ( &set_port.general, 3,
2471: pfcrx, ( 1 << FCOE_VLAN_PRIORITY ) );
2472: if ( ( rc = hermon_cmd_set_port ( hermon, 1,
2473: ( HERMON_SET_PORT_GENERAL_PARAM |
2474: ibdev->port ),
2475: &set_port ) ) != 0 ) {
2476: DBGC ( hermon, "Hermon %p port %d could not set port general "
2477: "parameters: %s\n",
2478: hermon, ibdev->port, strerror ( rc ) );
2479: goto err_set_port_general_params;
2480: }
2481:
2482: /* Set port receive QP */
2483: memset ( &set_port, 0, sizeof ( set_port ) );
2484: MLX_FILL_1 ( &set_port.rqp_calc, 0, base_qpn, port->eth_qp->qpn );
2485: MLX_FILL_1 ( &set_port.rqp_calc, 2,
2486: mac_miss_index, 128 /* MAC misses go to promisc QP */ );
2487: MLX_FILL_2 ( &set_port.rqp_calc, 3,
2488: vlan_miss_index, 127 /* VLAN misses go to promisc QP */,
2489: no_vlan_index, 126 /* VLAN-free go to promisc QP */ );
2490: MLX_FILL_2 ( &set_port.rqp_calc, 5,
2491: promisc_qpn, port->eth_qp->qpn,
2492: en_uc_promisc, 1 );
2493: MLX_FILL_2 ( &set_port.rqp_calc, 6,
2494: def_mcast_qpn, port->eth_qp->qpn,
2495: mc_promisc_mode, 2 /* Receive all multicasts */ );
2496: if ( ( rc = hermon_cmd_set_port ( hermon, 1,
2497: ( HERMON_SET_PORT_RECEIVE_QP |
2498: ibdev->port ),
2499: &set_port ) ) != 0 ) {
2500: DBGC ( hermon, "Hermon %p port %d could not set port receive "
2501: "QP: %s\n", hermon, ibdev->port, strerror ( rc ) );
2502: goto err_set_port_receive_qp;
2503: }
2504:
2505: /* Initialise port */
2506: if ( ( rc = hermon_cmd_init_port ( hermon, ibdev->port ) ) != 0 ) {
2507: DBGC ( hermon, "Hermon %p port %d could not initialise port: "
2508: "%s\n", hermon, ibdev->port, strerror ( rc ) );
2509: goto err_init_port;
2510: }
2511:
2512: return 0;
2513:
2514: err_init_port:
2515: err_set_port_receive_qp:
2516: err_set_port_general_params:
2517: err_modify_qp:
2518: ib_destroy_qp ( ibdev, port->eth_qp );
2519: err_create_qp:
2520: ib_destroy_cq ( ibdev, port->eth_cq );
2521: err_create_cq:
2522: return rc;
2523: }
2524:
2525: /**
2526: * Close Hermon Ethernet device
2527: *
2528: * @v netdev Network device
2529: */
2530: static void hermon_eth_close ( struct net_device *netdev ) {
2531: struct hermon_port *port = netdev->priv;
2532: struct ib_device *ibdev = port->ibdev;
2533: struct hermon *hermon = ib_get_drvdata ( ibdev );
2534: int rc;
2535:
2536: /* Close port */
2537: if ( ( rc = hermon_cmd_close_port ( hermon, ibdev->port ) ) != 0 ) {
2538: DBGC ( hermon, "Hermon %p port %d could not close port: %s\n",
2539: hermon, ibdev->port, strerror ( rc ) );
2540: /* Nothing we can do about this */
2541: }
2542:
2543: /* Tear down the queues */
2544: ib_destroy_qp ( ibdev, port->eth_qp );
2545: ib_destroy_cq ( ibdev, port->eth_cq );
2546: }
2547:
2548: /** Hermon Ethernet network device operations */
2549: static struct net_device_operations hermon_eth_operations = {
2550: .open = hermon_eth_open,
2551: .close = hermon_eth_close,
2552: .transmit = hermon_eth_transmit,
2553: .poll = hermon_eth_poll,
2554: };
2555:
2556: /**
2557: * Register Hermon Ethernet device
2558: *
2559: * @v hermon Hermon device
2560: * @v port Hermon port
2561: * @ret rc Return status code
2562: */
2563: static int hermon_register_netdev ( struct hermon *hermon,
2564: struct hermon_port *port ) {
2565: struct net_device *netdev = port->netdev;
2566: struct ib_device *ibdev = port->ibdev;
2567: struct hermonprm_query_port_cap query_port;
2568: union {
2569: uint8_t bytes[8];
2570: uint32_t dwords[2];
2571: } mac;
2572: int rc;
2573:
2574: /* Retrieve MAC address */
2575: if ( ( rc = hermon_cmd_query_port ( hermon, ibdev->port,
2576: &query_port ) ) != 0 ) {
2577: DBGC ( hermon, "Hermon %p port %d could not query port: %s\n",
2578: hermon, ibdev->port, strerror ( rc ) );
2579: return rc;
2580: }
2581: mac.dwords[0] = htonl ( MLX_GET ( &query_port, mac_47_32 ) );
2582: mac.dwords[1] = htonl ( MLX_GET ( &query_port, mac_31_0 ) );
2583: memcpy ( netdev->hw_addr,
2584: &mac.bytes[ sizeof ( mac.bytes ) - ETH_ALEN ], ETH_ALEN );
2585:
2586: /* Register network device */
2587: if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
2588: DBGC ( hermon, "Hermon %p port %d could not register network "
2589: "device: %s\n", hermon, ibdev->port, strerror ( rc ) );
2590: return rc;
2591: }
2592:
2593: return 0;
2594: }
2595:
2596: /**
2597: * Handle Hermon Ethernet device port state change
2598: *
2599: * @v hermon Hermon device
2600: * @v port Hermon port
2601: * @v link_up Link is up
2602: */
2603: static void hermon_state_change_netdev ( struct hermon *hermon __unused,
2604: struct hermon_port *port,
2605: int link_up ) {
2606: struct net_device *netdev = port->netdev;
2607:
2608: if ( link_up ) {
2609: netdev_link_up ( netdev );
2610: } else {
2611: netdev_link_down ( netdev );
2612: }
2613: }
2614:
2615: /**
2616: * Unregister Hermon Ethernet device
2617: *
2618: * @v hermon Hermon device
2619: * @v port Hermon port
2620: */
2621: static void hermon_unregister_netdev ( struct hermon *hermon __unused,
2622: struct hermon_port *port ) {
2623: struct net_device *netdev = port->netdev;
2624:
2625: unregister_netdev ( netdev );
2626: }
2627:
2628: /** Hermon Ethernet port type */
2629: static struct hermon_port_type hermon_port_type_eth = {
2630: .register_dev = hermon_register_netdev,
2631: .state_change = hermon_state_change_netdev,
2632: .unregister_dev = hermon_unregister_netdev,
2633: };
2634:
2635: /***************************************************************************
2636: *
2637: * Port type detection
2638: *
2639: ***************************************************************************
2640: */
2641:
2642: /** Timeout for port sensing */
2643: #define HERMON_SENSE_PORT_TIMEOUT ( TICKS_PER_SEC / 2 )
2644:
2645: /**
2646: * Name port type
2647: *
2648: * @v port_type Port type
2649: * @v port_type_name Port type name
2650: */
2651: static inline const char * hermon_name_port_type ( unsigned int port_type ) {
2652: switch ( port_type ) {
2653: case HERMON_PORT_TYPE_UNKNOWN: return "unknown";
2654: case HERMON_PORT_TYPE_IB: return "Infiniband";
2655: case HERMON_PORT_TYPE_ETH: return "Ethernet";
2656: default: return "INVALID";
2657: }
2658: }
2659:
2660: /**
2661: * Sense port type
2662: *
2663: * @v hermon Hermon device
2664: * @v port Hermon port
2665: * @ret port_type Port type, or negative error
2666: */
2667: static int hermon_sense_port_type ( struct hermon *hermon,
2668: struct hermon_port *port ) {
2669: struct ib_device *ibdev = port->ibdev;
2670: struct hermonprm_sense_port sense_port;
2671: int port_type;
2672: int rc;
2673:
2674: /* If DPDP is not supported, always assume Infiniband */
2675: if ( ! hermon->cap.dpdp ) {
2676: port_type = HERMON_PORT_TYPE_IB;
2677: DBGC ( hermon, "Hermon %p port %d does not support DPDP; "
2678: "assuming an %s network\n", hermon, ibdev->port,
2679: hermon_name_port_type ( port_type ) );
2680: return port_type;
2681: }
2682:
2683: /* Sense the port type */
2684: if ( ( rc = hermon_cmd_sense_port ( hermon, ibdev->port,
2685: &sense_port ) ) != 0 ) {
2686: DBGC ( hermon, "Hermon %p port %d sense failed: %s\n",
2687: hermon, ibdev->port, strerror ( rc ) );
2688: return rc;
2689: }
2690: port_type = MLX_GET ( &sense_port, port_type );
2691:
2692: DBGC ( hermon, "Hermon %p port %d sensed an %s network\n",
2693: hermon, ibdev->port, hermon_name_port_type ( port_type ) );
2694: return port_type;
2695: }
2696:
2697: /**
2698: * Set port type
2699: *
2700: * @v hermon Hermon device
2701: * @v port Hermon port
2702: * @ret rc Return status code
2703: */
2704: static int hermon_set_port_type ( struct hermon *hermon,
2705: struct hermon_port *port ) {
2706: struct ib_device *ibdev = port->ibdev;
2707: struct hermonprm_query_port_cap query_port;
2708: int ib_supported;
2709: int eth_supported;
2710: int port_type;
2711: unsigned long start;
2712: unsigned long elapsed;
2713: int rc;
2714:
2715: /* Check to see which types are supported */
2716: if ( ( rc = hermon_cmd_query_port ( hermon, ibdev->port,
2717: &query_port ) ) != 0 ) {
2718: DBGC ( hermon, "Hermon %p port %d could not query port: %s\n",
2719: hermon, ibdev->port, strerror ( rc ) );
2720: return rc;
2721: }
2722: ib_supported = MLX_GET ( &query_port, ib );
2723: eth_supported = MLX_GET ( &query_port, eth );
2724: DBGC ( hermon, "Hermon %p port %d supports%s%s%s\n",
2725: hermon, ibdev->port, ( ib_supported ? " Infiniband" : "" ),
2726: ( ( ib_supported && eth_supported ) ? " and" : "" ),
2727: ( eth_supported ? " Ethernet" : "" ) );
2728:
2729: /* Sense network, if applicable */
2730: if ( ib_supported && eth_supported ) {
2731:
2732: /* Both types are supported; try sensing network */
2733: start = currticks();
2734: do {
2735: /* Try sensing port */
2736: port_type = hermon_sense_port_type ( hermon, port );
2737: if ( port_type < 0 ) {
2738: rc = port_type;
2739: return rc;
2740: }
2741: } while ( ( port_type == HERMON_PORT_TYPE_UNKNOWN ) &&
2742: ( ( elapsed = ( currticks() - start ) ) <
2743: HERMON_SENSE_PORT_TIMEOUT ) );
2744:
2745: /* Set port type based on sensed network, defaulting
2746: * to Infiniband if nothing was sensed.
2747: */
2748: switch ( port_type ) {
2749: case HERMON_PORT_TYPE_ETH:
2750: port->type = &hermon_port_type_eth;
2751: break;
2752: case HERMON_PORT_TYPE_IB:
2753: case HERMON_PORT_TYPE_UNKNOWN:
2754: port->type = &hermon_port_type_ib;
2755: break;
2756: default:
2757: return -EINVAL;
2758: }
2759:
2760: } else if ( eth_supported ) {
2761: port->type = &hermon_port_type_eth;
2762: } else {
2763: port->type = &hermon_port_type_ib;
2764: }
2765:
2766: assert ( port->type != NULL );
2767: return 0;
2768: }
2769:
2770: /***************************************************************************
2771: *
2772: * Firmware control
2773: *
2774: ***************************************************************************
2775: */
2776:
2777: /**
2778: * Map virtual to physical address for firmware usage
2779: *
2780: * @v hermon Hermon device
2781: * @v map Mapping function
2782: * @v va Virtual address
2783: * @v pa Physical address
2784: * @v len Length of region
2785: * @ret rc Return status code
2786: */
2787: static int hermon_map_vpm ( struct hermon *hermon,
2788: int ( *map ) ( struct hermon *hermon,
2789: const struct hermonprm_virtual_physical_mapping* ),
2790: uint64_t va, physaddr_t pa, size_t len ) {
2791: struct hermonprm_virtual_physical_mapping mapping;
2792: physaddr_t start;
2793: physaddr_t low;
2794: physaddr_t high;
2795: physaddr_t end;
2796: size_t size;
2797: int rc;
2798:
2799: /* Sanity checks */
2800: assert ( ( va & ( HERMON_PAGE_SIZE - 1 ) ) == 0 );
2801: assert ( ( pa & ( HERMON_PAGE_SIZE - 1 ) ) == 0 );
2802: assert ( ( len & ( HERMON_PAGE_SIZE - 1 ) ) == 0 );
2803:
2804: /* Calculate starting points */
2805: start = pa;
2806: end = ( start + len );
2807: size = ( 1UL << ( fls ( start ^ end ) - 1 ) );
2808: low = high = ( end & ~( size - 1 ) );
2809: assert ( start < low );
2810: assert ( high <= end );
2811:
2812: /* These mappings tend to generate huge volumes of
2813: * uninteresting debug data, which basically makes it
2814: * impossible to use debugging otherwise.
2815: */
2816: DBG_DISABLE ( DBGLVL_LOG | DBGLVL_EXTRA );
2817:
2818: /* Map blocks in descending order of size */
2819: while ( size >= HERMON_PAGE_SIZE ) {
2820:
2821: /* Find the next candidate block */
2822: if ( ( low - size ) >= start ) {
2823: low -= size;
2824: pa = low;
2825: } else if ( ( high + size ) <= end ) {
2826: pa = high;
2827: high += size;
2828: } else {
2829: size >>= 1;
2830: continue;
2831: }
2832: assert ( ( va & ( size - 1 ) ) == 0 );
2833: assert ( ( pa & ( size - 1 ) ) == 0 );
2834:
2835: /* Map this block */
2836: memset ( &mapping, 0, sizeof ( mapping ) );
2837: MLX_FILL_1 ( &mapping, 0, va_h, ( va >> 32 ) );
2838: MLX_FILL_1 ( &mapping, 1, va_l, ( va >> 12 ) );
2839: MLX_FILL_H ( &mapping, 2, pa_h, pa );
2840: MLX_FILL_2 ( &mapping, 3,
2841: log2size, ( ( fls ( size ) - 1 ) - 12 ),
2842: pa_l, ( pa >> 12 ) );
2843: if ( ( rc = map ( hermon, &mapping ) ) != 0 ) {
2844: DBG_ENABLE ( DBGLVL_LOG | DBGLVL_EXTRA );
2845: DBGC ( hermon, "Hermon %p could not map %08llx+%zx to "
2846: "%08lx: %s\n",
2847: hermon, va, size, pa, strerror ( rc ) );
2848: return rc;
2849: }
2850: va += size;
2851: }
2852: assert ( low == start );
2853: assert ( high == end );
2854:
2855: DBG_ENABLE ( DBGLVL_LOG | DBGLVL_EXTRA );
2856: return 0;
2857: }
2858:
2859: /**
2860: * Start firmware running
2861: *
2862: * @v hermon Hermon device
2863: * @ret rc Return status code
2864: */
2865: static int hermon_start_firmware ( struct hermon *hermon ) {
2866: struct hermonprm_query_fw fw;
2867: unsigned int fw_pages;
2868: size_t fw_size;
2869: physaddr_t fw_base;
2870: int rc;
2871:
2872: /* Get firmware parameters */
2873: if ( ( rc = hermon_cmd_query_fw ( hermon, &fw ) ) != 0 ) {
2874: DBGC ( hermon, "Hermon %p could not query firmware: %s\n",
2875: hermon, strerror ( rc ) );
2876: goto err_query_fw;
2877: }
2878: DBGC ( hermon, "Hermon %p firmware version %d.%d.%d\n", hermon,
2879: MLX_GET ( &fw, fw_rev_major ), MLX_GET ( &fw, fw_rev_minor ),
2880: MLX_GET ( &fw, fw_rev_subminor ) );
2881: fw_pages = MLX_GET ( &fw, fw_pages );
2882: DBGC ( hermon, "Hermon %p requires %d pages (%d kB) for firmware\n",
2883: hermon, fw_pages, ( fw_pages * 4 ) );
2884:
2885: /* Allocate firmware pages and map firmware area */
2886: fw_size = ( fw_pages * HERMON_PAGE_SIZE );
2887: hermon->firmware_area = umalloc ( fw_size );
2888: if ( ! hermon->firmware_area ) {
2889: rc = -ENOMEM;
2890: goto err_alloc_fa;
2891: }
2892: fw_base = user_to_phys ( hermon->firmware_area, 0 );
2893: DBGC ( hermon, "Hermon %p firmware area at physical [%08lx,%08lx)\n",
2894: hermon, fw_base, ( fw_base + fw_size ) );
2895: if ( ( rc = hermon_map_vpm ( hermon, hermon_cmd_map_fa,
2896: 0, fw_base, fw_size ) ) != 0 ) {
2897: DBGC ( hermon, "Hermon %p could not map firmware: %s\n",
2898: hermon, strerror ( rc ) );
2899: goto err_map_fa;
2900: }
2901:
2902: /* Start firmware */
2903: if ( ( rc = hermon_cmd_run_fw ( hermon ) ) != 0 ) {
2904: DBGC ( hermon, "Hermon %p could not run firmware: %s\n",
2905: hermon, strerror ( rc ) );
2906: goto err_run_fw;
2907: }
2908:
2909: DBGC ( hermon, "Hermon %p firmware started\n", hermon );
2910: return 0;
2911:
2912: err_run_fw:
2913: err_map_fa:
2914: hermon_cmd_unmap_fa ( hermon );
2915: ufree ( hermon->firmware_area );
2916: hermon->firmware_area = UNULL;
2917: err_alloc_fa:
2918: err_query_fw:
2919: return rc;
2920: }
2921:
2922: /**
2923: * Stop firmware running
2924: *
2925: * @v hermon Hermon device
2926: */
2927: static void hermon_stop_firmware ( struct hermon *hermon ) {
2928: int rc;
2929:
2930: if ( ( rc = hermon_cmd_unmap_fa ( hermon ) ) != 0 ) {
2931: DBGC ( hermon, "Hermon %p FATAL could not stop firmware: %s\n",
2932: hermon, strerror ( rc ) );
2933: /* Leak memory and return; at least we avoid corruption */
2934: return;
2935: }
2936: ufree ( hermon->firmware_area );
2937: hermon->firmware_area = UNULL;
2938: }
2939:
2940: /***************************************************************************
2941: *
2942: * Infinihost Context Memory management
2943: *
2944: ***************************************************************************
2945: */
2946:
2947: /**
2948: * Get device limits
2949: *
2950: * @v hermon Hermon device
2951: * @ret rc Return status code
2952: */
2953: static int hermon_get_cap ( struct hermon *hermon ) {
2954: struct hermonprm_query_dev_cap dev_cap;
2955: int rc;
2956:
2957: if ( ( rc = hermon_cmd_query_dev_cap ( hermon, &dev_cap ) ) != 0 ) {
2958: DBGC ( hermon, "Hermon %p could not get device limits: %s\n",
2959: hermon, strerror ( rc ) );
2960: return rc;
2961: }
2962:
2963: hermon->cap.cmpt_entry_size = MLX_GET ( &dev_cap, c_mpt_entry_sz );
2964: hermon->cap.reserved_qps =
2965: ( 1 << MLX_GET ( &dev_cap, log2_rsvd_qps ) );
2966: hermon->cap.qpc_entry_size = MLX_GET ( &dev_cap, qpc_entry_sz );
2967: hermon->cap.altc_entry_size = MLX_GET ( &dev_cap, altc_entry_sz );
2968: hermon->cap.auxc_entry_size = MLX_GET ( &dev_cap, aux_entry_sz );
2969: hermon->cap.reserved_srqs =
2970: ( 1 << MLX_GET ( &dev_cap, log2_rsvd_srqs ) );
2971: hermon->cap.srqc_entry_size = MLX_GET ( &dev_cap, srq_entry_sz );
2972: hermon->cap.reserved_cqs =
2973: ( 1 << MLX_GET ( &dev_cap, log2_rsvd_cqs ) );
2974: hermon->cap.cqc_entry_size = MLX_GET ( &dev_cap, cqc_entry_sz );
2975: hermon->cap.reserved_eqs = MLX_GET ( &dev_cap, num_rsvd_eqs );
2976: if ( hermon->cap.reserved_eqs == 0 ) {
2977: /* Backward compatibility */
2978: hermon->cap.reserved_eqs =
2979: ( 1 << MLX_GET ( &dev_cap, log2_rsvd_eqs ) );
2980: }
2981: hermon->cap.eqc_entry_size = MLX_GET ( &dev_cap, eqc_entry_sz );
2982: hermon->cap.reserved_mtts =
2983: ( 1 << MLX_GET ( &dev_cap, log2_rsvd_mtts ) );
2984: hermon->cap.mtt_entry_size = MLX_GET ( &dev_cap, mtt_entry_sz );
2985: hermon->cap.reserved_mrws =
2986: ( 1 << MLX_GET ( &dev_cap, log2_rsvd_mrws ) );
2987: hermon->cap.dmpt_entry_size = MLX_GET ( &dev_cap, d_mpt_entry_sz );
2988: hermon->cap.reserved_uars = MLX_GET ( &dev_cap, num_rsvd_uars );
2989: hermon->cap.num_ports = MLX_GET ( &dev_cap, num_ports );
2990: hermon->cap.dpdp = MLX_GET ( &dev_cap, dpdp );
2991:
2992: /* Sanity check */
2993: if ( hermon->cap.num_ports > HERMON_MAX_PORTS ) {
2994: DBGC ( hermon, "Hermon %p has %d ports (only %d supported)\n",
2995: hermon, hermon->cap.num_ports, HERMON_MAX_PORTS );
2996: hermon->cap.num_ports = HERMON_MAX_PORTS;
2997: }
2998:
2999: return 0;
3000: }
3001:
3002: /**
3003: * Align ICM table
3004: *
3005: * @v icm_offset Current ICM offset
3006: * @v len ICM table length
3007: * @ret icm_offset ICM offset
3008: */
3009: static uint64_t icm_align ( uint64_t icm_offset, size_t len ) {
3010:
3011: /* Round up to a multiple of the table size */
3012: assert ( len == ( 1UL << ( fls ( len ) - 1 ) ) );
3013: return ( ( icm_offset + len - 1 ) & ~( ( ( uint64_t ) len ) - 1 ) );
3014: }
3015:
3016: /**
3017: * Allocate ICM
3018: *
3019: * @v hermon Hermon device
3020: * @v init_hca INIT_HCA structure to fill in
3021: * @ret rc Return status code
3022: */
3023: static int hermon_alloc_icm ( struct hermon *hermon,
3024: struct hermonprm_init_hca *init_hca ) {
3025: struct hermonprm_scalar_parameter icm_size;
3026: struct hermonprm_scalar_parameter icm_aux_size;
3027: uint64_t icm_offset = 0;
3028: unsigned int log_num_qps, log_num_srqs, log_num_cqs, log_num_eqs;
3029: unsigned int log_num_mtts, log_num_mpts, log_num_mcs;
3030: size_t cmpt_max_len;
3031: size_t icm_len, icm_aux_len;
3032: size_t len;
3033: physaddr_t icm_phys;
3034: int i;
3035: int rc;
3036:
3037: /*
3038: * Start by carving up the ICM virtual address space
3039: *
3040: */
3041:
3042: /* Calculate number of each object type within ICM */
3043: log_num_qps = fls ( hermon->cap.reserved_qps +
3044: HERMON_RSVD_SPECIAL_QPS + HERMON_MAX_QPS - 1 );
3045: log_num_srqs = fls ( hermon->cap.reserved_srqs - 1 );
3046: log_num_cqs = fls ( hermon->cap.reserved_cqs + HERMON_MAX_CQS - 1 );
3047: log_num_eqs = fls ( hermon->cap.reserved_eqs + HERMON_MAX_EQS - 1 );
3048: log_num_mtts = fls ( hermon->cap.reserved_mtts + HERMON_MAX_MTTS - 1 );
3049: log_num_mpts = fls ( hermon->cap.reserved_mrws + 1 - 1 );
3050: log_num_mcs = HERMON_LOG_MULTICAST_HASH_SIZE;
3051:
3052: /* ICM starts with the cMPT tables, which are sparse */
3053: cmpt_max_len = ( HERMON_CMPT_MAX_ENTRIES *
3054: ( ( uint64_t ) hermon->cap.cmpt_entry_size ) );
3055: len = ( ( ( ( 1 << log_num_qps ) * hermon->cap.cmpt_entry_size ) +
3056: HERMON_PAGE_SIZE - 1 ) & ~( HERMON_PAGE_SIZE - 1 ) );
3057: hermon->icm_map[HERMON_ICM_QP_CMPT].offset = icm_offset;
3058: hermon->icm_map[HERMON_ICM_QP_CMPT].len = len;
3059: icm_offset += cmpt_max_len;
3060: len = ( ( ( ( 1 << log_num_srqs ) * hermon->cap.cmpt_entry_size ) +
3061: HERMON_PAGE_SIZE - 1 ) & ~( HERMON_PAGE_SIZE - 1 ) );
3062: hermon->icm_map[HERMON_ICM_SRQ_CMPT].offset = icm_offset;
3063: hermon->icm_map[HERMON_ICM_SRQ_CMPT].len = len;
3064: icm_offset += cmpt_max_len;
3065: len = ( ( ( ( 1 << log_num_cqs ) * hermon->cap.cmpt_entry_size ) +
3066: HERMON_PAGE_SIZE - 1 ) & ~( HERMON_PAGE_SIZE - 1 ) );
3067: hermon->icm_map[HERMON_ICM_CQ_CMPT].offset = icm_offset;
3068: hermon->icm_map[HERMON_ICM_CQ_CMPT].len = len;
3069: icm_offset += cmpt_max_len;
3070: len = ( ( ( ( 1 << log_num_eqs ) * hermon->cap.cmpt_entry_size ) +
3071: HERMON_PAGE_SIZE - 1 ) & ~( HERMON_PAGE_SIZE - 1 ) );
3072: hermon->icm_map[HERMON_ICM_EQ_CMPT].offset = icm_offset;
3073: hermon->icm_map[HERMON_ICM_EQ_CMPT].len = len;
3074: icm_offset += cmpt_max_len;
3075:
3076: hermon->icm_map[HERMON_ICM_OTHER].offset = icm_offset;
3077:
3078: /* Queue pair contexts */
3079: len = ( ( 1 << log_num_qps ) * hermon->cap.qpc_entry_size );
3080: icm_offset = icm_align ( icm_offset, len );
3081: MLX_FILL_1 ( init_hca, 12,
3082: qpc_eec_cqc_eqc_rdb_parameters.qpc_base_addr_h,
3083: ( icm_offset >> 32 ) );
3084: MLX_FILL_2 ( init_hca, 13,
3085: qpc_eec_cqc_eqc_rdb_parameters.qpc_base_addr_l,
3086: ( icm_offset >> 5 ),
3087: qpc_eec_cqc_eqc_rdb_parameters.log_num_of_qp,
3088: log_num_qps );
3089: DBGC ( hermon, "Hermon %p ICM QPC is %d x %#zx at [%08llx,%08llx)\n",
3090: hermon, ( 1 << log_num_qps ), hermon->cap.qpc_entry_size,
3091: icm_offset, ( icm_offset + len ) );
3092: icm_offset += len;
3093:
3094: /* Extended alternate path contexts */
3095: len = ( ( 1 << log_num_qps ) * hermon->cap.altc_entry_size );
3096: icm_offset = icm_align ( icm_offset, len );
3097: MLX_FILL_1 ( init_hca, 24,
3098: qpc_eec_cqc_eqc_rdb_parameters.altc_base_addr_h,
3099: ( icm_offset >> 32 ) );
3100: MLX_FILL_1 ( init_hca, 25,
3101: qpc_eec_cqc_eqc_rdb_parameters.altc_base_addr_l,
3102: icm_offset );
3103: DBGC ( hermon, "Hermon %p ICM ALTC is %d x %#zx at [%08llx,%08llx)\n",
3104: hermon, ( 1 << log_num_qps ), hermon->cap.altc_entry_size,
3105: icm_offset, ( icm_offset + len ) );
3106: icm_offset += len;
3107:
3108: /* Extended auxiliary contexts */
3109: len = ( ( 1 << log_num_qps ) * hermon->cap.auxc_entry_size );
3110: icm_offset = icm_align ( icm_offset, len );
3111: MLX_FILL_1 ( init_hca, 28,
3112: qpc_eec_cqc_eqc_rdb_parameters.auxc_base_addr_h,
3113: ( icm_offset >> 32 ) );
3114: MLX_FILL_1 ( init_hca, 29,
3115: qpc_eec_cqc_eqc_rdb_parameters.auxc_base_addr_l,
3116: icm_offset );
3117: DBGC ( hermon, "Hermon %p ICM AUXC is %d x %#zx at [%08llx,%08llx)\n",
3118: hermon, ( 1 << log_num_qps ), hermon->cap.auxc_entry_size,
3119: icm_offset, ( icm_offset + len ) );
3120: icm_offset += len;
3121:
3122: /* Shared receive queue contexts */
3123: len = ( ( 1 << log_num_srqs ) * hermon->cap.srqc_entry_size );
3124: icm_offset = icm_align ( icm_offset, len );
3125: MLX_FILL_1 ( init_hca, 18,
3126: qpc_eec_cqc_eqc_rdb_parameters.srqc_base_addr_h,
3127: ( icm_offset >> 32 ) );
3128: MLX_FILL_2 ( init_hca, 19,
3129: qpc_eec_cqc_eqc_rdb_parameters.srqc_base_addr_l,
3130: ( icm_offset >> 5 ),
3131: qpc_eec_cqc_eqc_rdb_parameters.log_num_of_srq,
3132: log_num_srqs );
3133: DBGC ( hermon, "Hermon %p ICM SRQC is %d x %#zx at [%08llx,%08llx)\n",
3134: hermon, ( 1 << log_num_srqs ), hermon->cap.srqc_entry_size,
3135: icm_offset, ( icm_offset + len ) );
3136: icm_offset += len;
3137:
3138: /* Completion queue contexts */
3139: len = ( ( 1 << log_num_cqs ) * hermon->cap.cqc_entry_size );
3140: icm_offset = icm_align ( icm_offset, len );
3141: MLX_FILL_1 ( init_hca, 20,
3142: qpc_eec_cqc_eqc_rdb_parameters.cqc_base_addr_h,
3143: ( icm_offset >> 32 ) );
3144: MLX_FILL_2 ( init_hca, 21,
3145: qpc_eec_cqc_eqc_rdb_parameters.cqc_base_addr_l,
3146: ( icm_offset >> 5 ),
3147: qpc_eec_cqc_eqc_rdb_parameters.log_num_of_cq,
3148: log_num_cqs );
3149: DBGC ( hermon, "Hermon %p ICM CQC is %d x %#zx at [%08llx,%08llx)\n",
3150: hermon, ( 1 << log_num_cqs ), hermon->cap.cqc_entry_size,
3151: icm_offset, ( icm_offset + len ) );
3152: icm_offset += len;
3153:
3154: /* Event queue contexts */
3155: len = ( ( 1 << log_num_eqs ) * hermon->cap.eqc_entry_size );
3156: icm_offset = icm_align ( icm_offset, len );
3157: MLX_FILL_1 ( init_hca, 32,
3158: qpc_eec_cqc_eqc_rdb_parameters.eqc_base_addr_h,
3159: ( icm_offset >> 32 ) );
3160: MLX_FILL_2 ( init_hca, 33,
3161: qpc_eec_cqc_eqc_rdb_parameters.eqc_base_addr_l,
3162: ( icm_offset >> 5 ),
3163: qpc_eec_cqc_eqc_rdb_parameters.log_num_of_eq,
3164: log_num_eqs );
3165: DBGC ( hermon, "Hermon %p ICM EQC is %d x %#zx at [%08llx,%08llx)\n",
3166: hermon, ( 1 << log_num_eqs ), hermon->cap.eqc_entry_size,
3167: icm_offset, ( icm_offset + len ) );
3168: icm_offset += len;
3169:
3170: /* Memory translation table */
3171: len = ( ( 1 << log_num_mtts ) * hermon->cap.mtt_entry_size );
3172: icm_offset = icm_align ( icm_offset, len );
3173: MLX_FILL_1 ( init_hca, 64,
3174: tpt_parameters.mtt_base_addr_h, ( icm_offset >> 32 ) );
3175: MLX_FILL_1 ( init_hca, 65,
3176: tpt_parameters.mtt_base_addr_l, icm_offset );
3177: DBGC ( hermon, "Hermon %p ICM MTT is %d x %#zx at [%08llx,%08llx)\n",
3178: hermon, ( 1 << log_num_mtts ), hermon->cap.mtt_entry_size,
3179: icm_offset, ( icm_offset + len ) );
3180: icm_offset += len;
3181:
3182: /* Memory protection table */
3183: len = ( ( 1 << log_num_mpts ) * hermon->cap.dmpt_entry_size );
3184: icm_offset = icm_align ( icm_offset, len );
3185: MLX_FILL_1 ( init_hca, 60,
3186: tpt_parameters.dmpt_base_adr_h, ( icm_offset >> 32 ) );
3187: MLX_FILL_1 ( init_hca, 61,
3188: tpt_parameters.dmpt_base_adr_l, icm_offset );
3189: MLX_FILL_1 ( init_hca, 62,
3190: tpt_parameters.log_dmpt_sz, log_num_mpts );
3191: DBGC ( hermon, "Hermon %p ICM DMPT is %d x %#zx at [%08llx,%08llx)\n",
3192: hermon, ( 1 << log_num_mpts ), hermon->cap.dmpt_entry_size,
3193: icm_offset, ( icm_offset + len ) );
3194: icm_offset += len;
3195:
3196: /* Multicast table */
3197: len = ( ( 1 << log_num_mcs ) * sizeof ( struct hermonprm_mcg_entry ) );
3198: icm_offset = icm_align ( icm_offset, len );
3199: MLX_FILL_1 ( init_hca, 48,
3200: multicast_parameters.mc_base_addr_h,
3201: ( icm_offset >> 32 ) );
3202: MLX_FILL_1 ( init_hca, 49,
3203: multicast_parameters.mc_base_addr_l, icm_offset );
3204: MLX_FILL_1 ( init_hca, 52,
3205: multicast_parameters.log_mc_table_entry_sz,
3206: fls ( sizeof ( struct hermonprm_mcg_entry ) - 1 ) );
3207: MLX_FILL_1 ( init_hca, 53,
3208: multicast_parameters.log_mc_table_hash_sz, log_num_mcs );
3209: MLX_FILL_1 ( init_hca, 54,
3210: multicast_parameters.log_mc_table_sz, log_num_mcs );
3211: DBGC ( hermon, "Hermon %p ICM MC is %d x %#zx at [%08llx,%08llx)\n",
3212: hermon, ( 1 << log_num_mcs ),
3213: sizeof ( struct hermonprm_mcg_entry ),
3214: icm_offset, ( icm_offset + len ) );
3215: icm_offset += len;
3216:
3217:
3218: hermon->icm_map[HERMON_ICM_OTHER].len =
3219: ( icm_offset - hermon->icm_map[HERMON_ICM_OTHER].offset );
3220:
3221: /*
3222: * Allocate and map physical memory for (portions of) ICM
3223: *
3224: * Map is:
3225: * ICM AUX area (aligned to its own size)
3226: * cMPT areas
3227: * Other areas
3228: */
3229:
3230: /* Calculate physical memory required for ICM */
3231: icm_len = 0;
3232: for ( i = 0 ; i < HERMON_ICM_NUM_REGIONS ; i++ ) {
3233: icm_len += hermon->icm_map[i].len;
3234: }
3235:
3236: /* Get ICM auxiliary area size */
3237: memset ( &icm_size, 0, sizeof ( icm_size ) );
3238: MLX_FILL_1 ( &icm_size, 0, value_hi, ( icm_offset >> 32 ) );
3239: MLX_FILL_1 ( &icm_size, 1, value, icm_offset );
3240: if ( ( rc = hermon_cmd_set_icm_size ( hermon, &icm_size,
3241: &icm_aux_size ) ) != 0 ) {
3242: DBGC ( hermon, "Hermon %p could not set ICM size: %s\n",
3243: hermon, strerror ( rc ) );
3244: goto err_set_icm_size;
3245: }
3246: icm_aux_len = ( MLX_GET ( &icm_aux_size, value ) * HERMON_PAGE_SIZE );
3247:
3248: /* Allocate ICM data and auxiliary area */
3249: DBGC ( hermon, "Hermon %p requires %zd kB ICM and %zd kB AUX ICM\n",
3250: hermon, ( icm_len / 1024 ), ( icm_aux_len / 1024 ) );
3251: hermon->icm = umalloc ( icm_aux_len + icm_len );
3252: if ( ! hermon->icm ) {
3253: rc = -ENOMEM;
3254: goto err_alloc;
3255: }
3256: icm_phys = user_to_phys ( hermon->icm, 0 );
3257:
3258: /* Map ICM auxiliary area */
3259: DBGC ( hermon, "Hermon %p mapping ICM AUX => %08lx\n",
3260: hermon, icm_phys );
3261: if ( ( rc = hermon_map_vpm ( hermon, hermon_cmd_map_icm_aux,
3262: 0, icm_phys, icm_aux_len ) ) != 0 ) {
3263: DBGC ( hermon, "Hermon %p could not map AUX ICM: %s\n",
3264: hermon, strerror ( rc ) );
3265: goto err_map_icm_aux;
3266: }
3267: icm_phys += icm_aux_len;
3268:
3269: /* MAP ICM area */
3270: for ( i = 0 ; i < HERMON_ICM_NUM_REGIONS ; i++ ) {
3271: DBGC ( hermon, "Hermon %p mapping ICM %llx+%zx => %08lx\n",
3272: hermon, hermon->icm_map[i].offset,
3273: hermon->icm_map[i].len, icm_phys );
3274: if ( ( rc = hermon_map_vpm ( hermon, hermon_cmd_map_icm,
3275: hermon->icm_map[i].offset,
3276: icm_phys,
3277: hermon->icm_map[i].len ) ) != 0 ){
3278: DBGC ( hermon, "Hermon %p could not map ICM: %s\n",
3279: hermon, strerror ( rc ) );
3280: goto err_map_icm;
3281: }
3282: icm_phys += hermon->icm_map[i].len;
3283: }
3284:
3285: return 0;
3286:
3287: err_map_icm:
3288: assert ( i == 0 ); /* We don't handle partial failure at present */
3289: err_map_icm_aux:
3290: hermon_cmd_unmap_icm_aux ( hermon );
3291: ufree ( hermon->icm );
3292: hermon->icm = UNULL;
3293: err_alloc:
3294: err_set_icm_size:
3295: return rc;
3296: }
3297:
3298: /**
3299: * Free ICM
3300: *
3301: * @v hermon Hermon device
3302: */
3303: static void hermon_free_icm ( struct hermon *hermon ) {
3304: struct hermonprm_scalar_parameter unmap_icm;
3305: int i;
3306:
3307: for ( i = ( HERMON_ICM_NUM_REGIONS - 1 ) ; i >= 0 ; i-- ) {
3308: memset ( &unmap_icm, 0, sizeof ( unmap_icm ) );
3309: MLX_FILL_1 ( &unmap_icm, 0, value_hi,
3310: ( hermon->icm_map[i].offset >> 32 ) );
3311: MLX_FILL_1 ( &unmap_icm, 1, value,
3312: hermon->icm_map[i].offset );
3313: hermon_cmd_unmap_icm ( hermon,
3314: ( 1 << fls ( ( hermon->icm_map[i].len /
3315: HERMON_PAGE_SIZE ) - 1)),
3316: &unmap_icm );
3317: }
3318: hermon_cmd_unmap_icm_aux ( hermon );
3319: ufree ( hermon->icm );
3320: hermon->icm = UNULL;
3321: }
3322:
3323: /***************************************************************************
3324: *
3325: * BOFM interface
3326: *
3327: ***************************************************************************
3328: */
3329:
3330: /**
3331: * Harvest Ethernet MAC for BOFM
3332: *
3333: * @v bofm BOFM device
3334: * @v mport Multi-port index
3335: * @v mac MAC to fill in
3336: * @ret rc Return status code
3337: */
3338: static int hermon_bofm_harvest ( struct bofm_device *bofm, unsigned int mport,
3339: uint8_t *mac ) {
3340: struct hermon *hermon = container_of ( bofm, struct hermon, bofm );
3341: struct hermonprm_mod_stat_cfg stat_cfg;
3342: union {
3343: uint8_t bytes[8];
3344: uint32_t dwords[2];
3345: } buf;
3346: int rc;
3347:
3348: /* Query static configuration */
3349: if ( ( rc = hermon_mod_stat_cfg ( hermon, mport,
3350: HERMON_MOD_STAT_CFG_QUERY,
3351: HERMON_MOD_STAT_CFG_OFFSET ( mac_m ),
3352: &stat_cfg ) ) != 0 ) {
3353: DBGC ( hermon, "Hermon %p port %d could not query "
3354: "configuration: %s\n", hermon, mport, strerror ( rc ) );
3355: return rc;
3356: }
3357:
3358: /* Retrieve MAC address */
3359: buf.dwords[0] = htonl ( MLX_GET ( &stat_cfg, mac_high ) );
3360: buf.dwords[1] = htonl ( MLX_GET ( &stat_cfg, mac_low ) );
3361: memcpy ( mac, &buf.bytes[ sizeof ( buf.bytes ) - ETH_ALEN ],
3362: ETH_ALEN );
3363:
3364: DBGC ( hermon, "Hermon %p port %d harvested MAC address %s\n",
3365: hermon, mport, eth_ntoa ( mac ) );
3366:
3367: return 0;
3368: }
3369:
3370: /**
3371: * Update Ethernet MAC for BOFM
3372: *
3373: * @v bofm BOFM device
3374: * @v mport Multi-port index
3375: * @v mac MAC to fill in
3376: * @ret rc Return status code
3377: */
3378: static int hermon_bofm_update ( struct bofm_device *bofm, unsigned int mport,
3379: const uint8_t *mac ) {
3380: struct hermon *hermon = container_of ( bofm, struct hermon, bofm );
3381: struct hermonprm_mod_stat_cfg stat_cfg;
3382: union {
3383: uint8_t bytes[8];
3384: uint32_t dwords[2];
3385: uint64_t qword;
3386: } buf;
3387: uint8_t *mac_copy = &buf.bytes[ sizeof ( buf.bytes ) - ETH_ALEN ];
3388: int rc;
3389:
3390: /* Prepare MAC address */
3391: memset ( &buf, 0, sizeof ( buf ) );
3392: memcpy ( mac_copy, mac, ETH_ALEN );
3393:
3394: /* Current BOFM versions are unable to create entries with
3395: * mport>1, which means that only the port 1 MAC address can
3396: * be explicitly specified. Work around this by using the
3397: * provided MAC address as a base address for all subsequent
3398: * ports. For example, if BOFM assigns the address
3399: *
3400: * 00:1A:64:76:00:09 for port 1
3401: *
3402: * then we will assign the addresses
3403: *
3404: * 00:1A:64:76:00:09 for port 1
3405: * 00:1A:64:76:00:0a for port 2
3406: *
3407: * Note that hermon->cap.num_ports is not yet defined at this
3408: * point.
3409: */
3410: for ( ; mport <= HERMON_MAX_PORTS ; mport++ ) {
3411:
3412: /* Modify static configuration */
3413: memset ( &stat_cfg, 0, sizeof ( stat_cfg ) );
3414: MLX_FILL_2 ( &stat_cfg, 36,
3415: mac_m, 1,
3416: mac_high, ntohl ( buf.dwords[0] ) );
3417: MLX_FILL_1 ( &stat_cfg, 37, mac_low, ntohl ( buf.dwords[1] ) );
3418: if ( ( rc = hermon_mod_stat_cfg ( hermon, mport,
3419: HERMON_MOD_STAT_CFG_SET,
3420: HERMON_MOD_STAT_CFG_OFFSET ( mac_m ),
3421: &stat_cfg ) ) != 0 ) {
3422: DBGC ( hermon, "Hermon %p port %d could not modify "
3423: "configuration: %s\n",
3424: hermon, mport, strerror ( rc ) );
3425: return rc;
3426: }
3427:
3428: DBGC ( hermon, "Hermon %p port %d updated MAC address to %s\n",
3429: hermon, mport, eth_ntoa ( mac_copy ) );
3430:
3431: /* Increment MAC address */
3432: buf.qword = cpu_to_be64 ( be64_to_cpu ( buf.qword ) + 1 );
3433: }
3434:
3435: return 0;
3436: }
3437:
3438: /** Hermon BOFM operations */
3439: static struct bofm_operations hermon_bofm_operations = {
3440: .harvest = hermon_bofm_harvest,
3441: .update = hermon_bofm_update,
3442: };
3443:
3444: /***************************************************************************
3445: *
3446: * PCI interface
3447: *
3448: ***************************************************************************
3449: */
3450:
3451: /**
3452: * Set up memory protection table
3453: *
3454: * @v hermon Hermon device
3455: * @ret rc Return status code
3456: */
3457: static int hermon_setup_mpt ( struct hermon *hermon ) {
3458: struct hermonprm_mpt mpt;
3459: uint32_t key;
3460: int rc;
3461:
3462: /* Derive key */
3463: key = ( hermon->cap.reserved_mrws | HERMON_MKEY_PREFIX );
3464: hermon->lkey = ( ( key << 8 ) | ( key >> 24 ) );
3465:
3466: /* Initialise memory protection table */
3467: memset ( &mpt, 0, sizeof ( mpt ) );
3468: MLX_FILL_7 ( &mpt, 0,
3469: atomic, 1,
3470: rw, 1,
3471: rr, 1,
3472: lw, 1,
3473: lr, 1,
3474: pa, 1,
3475: r_w, 1 );
3476: MLX_FILL_1 ( &mpt, 2, mem_key, key );
3477: MLX_FILL_1 ( &mpt, 3,
3478: pd, HERMON_GLOBAL_PD );
3479: MLX_FILL_1 ( &mpt, 10, len64, 1 );
3480: if ( ( rc = hermon_cmd_sw2hw_mpt ( hermon,
3481: hermon->cap.reserved_mrws,
3482: &mpt ) ) != 0 ) {
3483: DBGC ( hermon, "Hermon %p could not set up MPT: %s\n",
3484: hermon, strerror ( rc ) );
3485: return rc;
3486: }
3487:
3488: return 0;
3489: }
3490:
3491: /**
3492: * Configure special queue pairs
3493: *
3494: * @v hermon Hermon device
3495: * @ret rc Return status code
3496: */
3497: static int hermon_configure_special_qps ( struct hermon *hermon ) {
3498: int rc;
3499:
3500: /* Special QP block must be aligned on its own size */
3501: hermon->special_qpn_base = ( ( hermon->cap.reserved_qps +
3502: HERMON_NUM_SPECIAL_QPS - 1 )
3503: & ~( HERMON_NUM_SPECIAL_QPS - 1 ) );
3504: hermon->qpn_base = ( hermon->special_qpn_base +
3505: HERMON_NUM_SPECIAL_QPS );
3506: DBGC ( hermon, "Hermon %p special QPs at [%lx,%lx]\n", hermon,
3507: hermon->special_qpn_base, ( hermon->qpn_base - 1 ) );
3508:
3509: /* Issue command to configure special QPs */
3510: if ( ( rc = hermon_cmd_conf_special_qp ( hermon, 0x00,
3511: hermon->special_qpn_base ) ) != 0 ) {
3512: DBGC ( hermon, "Hermon %p could not configure special QPs: "
3513: "%s\n", hermon, strerror ( rc ) );
3514: return rc;
3515: }
3516:
3517: return 0;
3518: }
3519:
3520: /**
3521: * Reset device
3522: *
3523: * @v hermon Hermon device
3524: * @v pci PCI device
3525: */
3526: static void hermon_reset ( struct hermon *hermon,
3527: struct pci_device *pci ) {
3528: struct pci_config_backup backup;
3529: static const uint8_t backup_exclude[] =
3530: PCI_CONFIG_BACKUP_EXCLUDE ( 0x58, 0x5c );
3531:
3532: pci_backup ( pci, &backup, backup_exclude );
3533: writel ( HERMON_RESET_MAGIC,
3534: ( hermon->config + HERMON_RESET_OFFSET ) );
3535: mdelay ( HERMON_RESET_WAIT_TIME_MS );
3536: pci_restore ( pci, &backup, backup_exclude );
3537: }
3538:
3539: /**
3540: * Allocate Hermon device
3541: *
3542: * @v pci PCI device
3543: * @v id PCI ID
3544: * @ret rc Return status code
3545: */
3546: static struct hermon * hermon_alloc ( void ) {
3547: struct hermon *hermon;
3548:
3549: /* Allocate Hermon device */
3550: hermon = zalloc ( sizeof ( *hermon ) );
3551: if ( ! hermon )
3552: goto err_hermon;
3553:
3554: /* Allocate space for mailboxes */
3555: hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE,
3556: HERMON_MBOX_ALIGN );
3557: if ( ! hermon->mailbox_in )
3558: goto err_mailbox_in;
3559: hermon->mailbox_out = malloc_dma ( HERMON_MBOX_SIZE,
3560: HERMON_MBOX_ALIGN );
3561: if ( ! hermon->mailbox_out )
3562: goto err_mailbox_out;
3563:
3564: return hermon;
3565:
3566: free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
3567: err_mailbox_out:
3568: free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
3569: err_mailbox_in:
3570: free ( hermon );
3571: err_hermon:
3572: return NULL;
3573: }
3574:
3575: /**
3576: * Free Hermon device
3577: *
3578: * @v hermon Hermon device
3579: */
3580: static void hermon_free ( struct hermon *hermon ) {
3581:
3582: free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
3583: free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
3584: free ( hermon );
3585: }
3586:
3587: /**
3588: * Initialise Hermon PCI parameters
3589: *
3590: * @v hermon Hermon device
3591: * @v pci PCI device
3592: */
3593: static void hermon_pci_init ( struct hermon *hermon, struct pci_device *pci ) {
3594:
3595: /* Fix up PCI device */
3596: adjust_pci_device ( pci );
3597:
3598: /* Get PCI BARs */
3599: hermon->config = ioremap ( pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR),
3600: HERMON_PCI_CONFIG_BAR_SIZE );
3601: hermon->uar = ioremap ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ),
3602: HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
3603: }
3604:
3605: /**
3606: * Probe PCI device
3607: *
3608: * @v pci PCI device
3609: * @v id PCI ID
3610: * @ret rc Return status code
3611: */
3612: static int hermon_probe ( struct pci_device *pci ) {
3613: struct hermon *hermon;
3614: struct ib_device *ibdev;
3615: struct net_device *netdev;
3616: struct hermon_port *port;
3617: struct hermonprm_init_hca init_hca;
3618: unsigned int i;
3619: int rc;
3620:
3621: /* Allocate Hermon device */
3622: hermon = hermon_alloc();
3623: if ( ! hermon ) {
3624: rc = -ENOMEM;
3625: goto err_alloc;
3626: }
3627: pci_set_drvdata ( pci, hermon );
3628:
3629: /* Initialise PCI parameters */
3630: hermon_pci_init ( hermon, pci );
3631:
3632: /* Reset device */
3633: hermon_reset ( hermon, pci );
3634:
3635: /* Start firmware */
3636: if ( ( rc = hermon_start_firmware ( hermon ) ) != 0 )
3637: goto err_start_firmware;
3638:
3639: /* Get device limits */
3640: if ( ( rc = hermon_get_cap ( hermon ) ) != 0 )
3641: goto err_get_cap;
3642:
3643: /* Allocate Infiniband devices */
3644: for ( i = 0 ; i < hermon->cap.num_ports ; i++ ) {
3645: ibdev = alloc_ibdev ( 0 );
3646: if ( ! ibdev ) {
3647: rc = -ENOMEM;
3648: goto err_alloc_ibdev;
3649: }
3650: hermon->port[i].ibdev = ibdev;
3651: ibdev->op = &hermon_ib_operations;
3652: ibdev->dev = &pci->dev;
3653: ibdev->port = ( HERMON_PORT_BASE + i );
3654: ib_set_drvdata ( ibdev, hermon );
3655: }
3656:
3657: /* Allocate network devices */
3658: for ( i = 0 ; i < hermon->cap.num_ports ; i++ ) {
3659: netdev = alloc_etherdev ( 0 );
3660: if ( ! netdev ) {
3661: rc = -ENOMEM;
3662: goto err_alloc_netdev;
3663: }
3664: hermon->port[i].netdev = netdev;
3665: netdev_init ( netdev, &hermon_eth_operations );
3666: netdev->dev = &pci->dev;
3667: netdev->priv = &hermon->port[i];
3668: }
3669:
3670: /* Allocate ICM */
3671: memset ( &init_hca, 0, sizeof ( init_hca ) );
3672: if ( ( rc = hermon_alloc_icm ( hermon, &init_hca ) ) != 0 )
3673: goto err_alloc_icm;
3674:
3675: /* Initialise HCA */
3676: MLX_FILL_1 ( &init_hca, 0, version, 0x02 /* "Must be 0x02" */ );
3677: MLX_FILL_1 ( &init_hca, 5, udp, 1 );
3678: MLX_FILL_1 ( &init_hca, 74, uar_parameters.log_max_uars, 8 );
3679: if ( ( rc = hermon_cmd_init_hca ( hermon, &init_hca ) ) != 0 ) {
3680: DBGC ( hermon, "Hermon %p could not initialise HCA: %s\n",
3681: hermon, strerror ( rc ) );
3682: goto err_init_hca;
3683: }
3684:
3685: /* Set up memory protection */
3686: if ( ( rc = hermon_setup_mpt ( hermon ) ) != 0 )
3687: goto err_setup_mpt;
3688: for ( i = 0 ; i < hermon->cap.num_ports ; i++ )
3689: hermon->port[i].ibdev->rdma_key = hermon->lkey;
3690:
3691: /* Set up event queue */
3692: if ( ( rc = hermon_create_eq ( hermon ) ) != 0 )
3693: goto err_create_eq;
3694:
3695: /* Configure special QPs */
3696: if ( ( rc = hermon_configure_special_qps ( hermon ) ) != 0 )
3697: goto err_conf_special_qps;
3698:
3699: /* Determine port types */
3700: for ( i = 0 ; i < hermon->cap.num_ports ; i++ ) {
3701: port = &hermon->port[i];
3702: if ( ( rc = hermon_set_port_type ( hermon, port ) ) != 0 )
3703: goto err_set_port_type;
3704: }
3705:
3706: /* Register devices */
3707: for ( i = 0 ; i < hermon->cap.num_ports ; i++ ) {
3708: port = &hermon->port[i];
3709: if ( ( rc = port->type->register_dev ( hermon, port ) ) != 0 )
3710: goto err_register;
3711: }
3712:
3713: return 0;
3714:
3715: i = hermon->cap.num_ports;
3716: err_register:
3717: for ( i-- ; ( signed int ) i >= 0 ; i-- ) {
3718: port = &hermon->port[i];
3719: port->type->unregister_dev ( hermon, port );
3720: }
3721: err_set_port_type:
3722: err_conf_special_qps:
3723: hermon_destroy_eq ( hermon );
3724: err_create_eq:
3725: err_setup_mpt:
3726: hermon_cmd_close_hca ( hermon );
3727: err_init_hca:
3728: hermon_free_icm ( hermon );
3729: err_alloc_icm:
3730: i = hermon->cap.num_ports;
3731: err_alloc_netdev:
3732: for ( i-- ; ( signed int ) i >= 0 ; i-- ) {
3733: netdev_nullify ( hermon->port[i].netdev );
3734: netdev_put ( hermon->port[i].netdev );
3735: }
3736: i = hermon->cap.num_ports;
3737: err_alloc_ibdev:
3738: for ( i-- ; ( signed int ) i >= 0 ; i-- )
3739: ibdev_put ( hermon->port[i].ibdev );
3740: err_get_cap:
3741: hermon_stop_firmware ( hermon );
3742: err_start_firmware:
3743: hermon_free ( hermon );
3744: err_alloc:
3745: return rc;
3746: }
3747:
3748: /**
3749: * Remove PCI device
3750: *
3751: * @v pci PCI device
3752: */
3753: static void hermon_remove ( struct pci_device *pci ) {
3754: struct hermon *hermon = pci_get_drvdata ( pci );
3755: struct hermon_port *port;
3756: int i;
3757:
3758: for ( i = ( hermon->cap.num_ports - 1 ) ; i >= 0 ; i-- ) {
3759: port = &hermon->port[i];
3760: port->type->unregister_dev ( hermon, port );
3761: }
3762: hermon_destroy_eq ( hermon );
3763: hermon_cmd_close_hca ( hermon );
3764: hermon_free_icm ( hermon );
3765: hermon_stop_firmware ( hermon );
3766: for ( i = ( hermon->cap.num_ports - 1 ) ; i >= 0 ; i-- ) {
3767: netdev_nullify ( hermon->port[i].netdev );
3768: netdev_put ( hermon->port[i].netdev );
3769: }
3770: for ( i = ( hermon->cap.num_ports - 1 ) ; i >= 0 ; i-- )
3771: ibdev_put ( hermon->port[i].ibdev );
3772: hermon_free ( hermon );
3773: }
3774:
3775: /**
3776: * Probe PCI device for BOFM
3777: *
3778: * @v pci PCI device
3779: * @v id PCI ID
3780: * @ret rc Return status code
3781: */
3782: static int hermon_bofm_probe ( struct pci_device *pci ) {
3783: struct hermon *hermon;
3784: int rc;
3785:
3786: /* Allocate Hermon device */
3787: hermon = hermon_alloc();
3788: if ( ! hermon ) {
3789: rc = -ENOMEM;
3790: goto err_alloc;
3791: }
3792: pci_set_drvdata ( pci, hermon );
3793:
3794: /* Initialise PCI parameters */
3795: hermon_pci_init ( hermon, pci );
3796:
3797: /* Initialise BOFM device */
3798: bofm_init ( &hermon->bofm, pci, &hermon_bofm_operations );
3799:
3800: /* Register BOFM device */
3801: if ( ( rc = bofm_register ( &hermon->bofm ) ) != 0 ) {
3802: DBGC ( hermon, "Hermon %p could not register BOFM device: "
3803: "%s\n", hermon, strerror ( rc ) );
3804: goto err_bofm_register;
3805: }
3806:
3807: return 0;
3808:
3809: err_bofm_register:
3810: hermon_free ( hermon );
3811: err_alloc:
3812: return rc;
3813: }
3814:
3815: /**
3816: * Remove PCI device for BOFM
3817: *
3818: * @v pci PCI device
3819: */
3820: static void hermon_bofm_remove ( struct pci_device *pci ) {
3821: struct hermon *hermon = pci_get_drvdata ( pci );
3822:
3823: bofm_unregister ( &hermon->bofm );
3824: hermon_free ( hermon );
3825: }
3826:
3827: static struct pci_device_id hermon_nics[] = {
3828: PCI_ROM ( 0x15b3, 0x6340, "mt25408", "MT25408 HCA driver", 0 ),
3829: PCI_ROM ( 0x15b3, 0x634a, "mt25418", "MT25418 HCA driver", 0 ),
3830: PCI_ROM ( 0x15b3, 0x6732, "mt26418", "MT26418 HCA driver", 0 ),
3831: PCI_ROM ( 0x15b3, 0x673c, "mt26428", "MT26428 HCA driver", 0 ),
3832: PCI_ROM ( 0x15b3, 0x6746, "mt26438", "MT26438 HCA driver", 0 ),
3833: PCI_ROM ( 0x15b3, 0x6778, "mt26488", "MT26488 HCA driver", 0 ),
3834: PCI_ROM ( 0x15b3, 0x6368, "mt25448", "MT25448 HCA driver", 0 ),
3835: PCI_ROM ( 0x15b3, 0x6750, "mt26448", "MT26448 HCA driver", 0 ),
3836: PCI_ROM ( 0x15b3, 0x6372, "mt25458", "MT25458 HCA driver", 0 ),
3837: PCI_ROM ( 0x15b3, 0x675a, "mt26458", "MT26458 HCA driver", 0 ),
3838: PCI_ROM ( 0x15b3, 0x6764, "mt26468", "MT26468 HCA driver", 0 ),
3839: PCI_ROM ( 0x15b3, 0x676e, "mt26478", "MT26478 HCA driver", 0 ),
3840: };
3841:
3842: struct pci_driver hermon_driver __pci_driver = {
3843: .ids = hermon_nics,
3844: .id_count = ( sizeof ( hermon_nics ) / sizeof ( hermon_nics[0] ) ),
3845: .probe = hermon_probe,
3846: .remove = hermon_remove,
3847: };
3848:
3849: struct pci_driver hermon_bofm_driver __bofm_driver = {
3850: .ids = hermon_nics,
3851: .id_count = ( sizeof ( hermon_nics ) / sizeof ( hermon_nics[0] ) ),
3852: .probe = hermon_bofm_probe,
3853: .remove = hermon_bofm_remove,
3854: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.