|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 2009 Michael Brown <[email protected]>. ! 3: * ! 4: * This program is free software; you can redistribute it and/or ! 5: * modify it under the terms of the GNU General Public License as ! 6: * published by the Free Software Foundation; either version 2 of the ! 7: * License, or any later version. ! 8: * ! 9: * This program is distributed in the hope that it will be useful, but ! 10: * WITHOUT ANY WARRANTY; without even the implied warranty of ! 11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 12: * General Public License for more details. ! 13: * ! 14: * You should have received a copy of the GNU General Public License ! 15: * along with this program; if not, write to the Free Software ! 16: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 17: */ ! 18: ! 19: FILE_LICENCE ( GPL2_OR_LATER ); ! 20: ! 21: #include <stdint.h> ! 22: #include <stdlib.h> ! 23: #include <errno.h> ! 24: #include <unistd.h> ! 25: #include <assert.h> ! 26: #include <ipxe/io.h> ! 27: #include <ipxe/pci.h> ! 28: #include <ipxe/infiniband.h> ! 29: #include <ipxe/i2c.h> ! 30: #include <ipxe/bitbash.h> ! 31: #include <ipxe/malloc.h> ! 32: #include <ipxe/iobuf.h> ! 33: #include <ipxe/pcibackup.h> ! 34: #include "qib7322.h" ! 35: ! 36: /** ! 37: * @file ! 38: * ! 39: * QLogic QIB7322 Infiniband HCA ! 40: * ! 41: */ ! 42: ! 43: /** A QIB7322 send buffer set */ ! 44: struct qib7322_send_buffers { ! 45: /** Offset within register space of the first send buffer */ ! 46: unsigned long base; ! 47: /** Send buffer size */ ! 48: unsigned int size; ! 49: /** Index of first send buffer */ ! 50: unsigned int start; ! 51: /** Number of send buffers ! 52: * ! 53: * Must be a power of two. ! 54: */ ! 55: unsigned int count; ! 56: /** Send buffer availability producer counter */ ! 57: unsigned int prod; ! 58: /** Send buffer availability consumer counter */ ! 59: unsigned int cons; ! 60: /** Send buffer availability */ ! 61: uint16_t avail[0]; ! 62: }; ! 63: ! 64: /** A QIB7322 send work queue */ ! 65: struct qib7322_send_work_queue { ! 66: /** Send buffer set */ ! 67: struct qib7322_send_buffers *send_bufs; ! 68: /** Send buffer usage */ ! 69: uint16_t *used; ! 70: /** Producer index */ ! 71: unsigned int prod; ! 72: /** Consumer index */ ! 73: unsigned int cons; ! 74: }; ! 75: ! 76: /** A QIB7322 receive work queue */ ! 77: struct qib7322_recv_work_queue { ! 78: /** Receive header ring */ ! 79: void *header; ! 80: /** Receive header producer offset (written by hardware) */ ! 81: struct QIB_7322_scalar header_prod; ! 82: /** Receive header consumer offset */ ! 83: unsigned int header_cons; ! 84: /** Offset within register space of the eager array */ ! 85: unsigned long eager_array; ! 86: /** Number of entries in eager array */ ! 87: unsigned int eager_entries; ! 88: /** Eager array producer index */ ! 89: unsigned int eager_prod; ! 90: /** Eager array consumer index */ ! 91: unsigned int eager_cons; ! 92: }; ! 93: ! 94: /** A QIB7322 HCA */ ! 95: struct qib7322 { ! 96: /** Registers */ ! 97: void *regs; ! 98: ! 99: /** In-use contexts */ ! 100: uint8_t used_ctx[QIB7322_NUM_CONTEXTS]; ! 101: /** Send work queues */ ! 102: struct qib7322_send_work_queue send_wq[QIB7322_NUM_CONTEXTS]; ! 103: /** Receive work queues */ ! 104: struct qib7322_recv_work_queue recv_wq[QIB7322_NUM_CONTEXTS]; ! 105: ! 106: /** Send buffer availability (reported by hardware) */ ! 107: struct QIB_7322_SendBufAvail *sendbufavail; ! 108: /** Small send buffers */ ! 109: struct qib7322_send_buffers *send_bufs_small; ! 110: /** VL15 port 0 send buffers */ ! 111: struct qib7322_send_buffers *send_bufs_vl15_port0; ! 112: /** VL15 port 1 send buffers */ ! 113: struct qib7322_send_buffers *send_bufs_vl15_port1; ! 114: ! 115: /** I2C bit-bashing interface */ ! 116: struct i2c_bit_basher i2c; ! 117: /** I2C serial EEPROM */ ! 118: struct i2c_device eeprom; ! 119: ! 120: /** Base GUID */ ! 121: union ib_guid guid; ! 122: /** Infiniband devices */ ! 123: struct ib_device *ibdev[QIB7322_MAX_PORTS]; ! 124: }; ! 125: ! 126: /*************************************************************************** ! 127: * ! 128: * QIB7322 register access ! 129: * ! 130: *************************************************************************** ! 131: * ! 132: * This card requires atomic 64-bit accesses. Strange things happen ! 133: * if you try to use 32-bit accesses; sometimes they work, sometimes ! 134: * they don't, sometimes you get random data. ! 135: * ! 136: * These accessors use the "movq" MMX instruction, and so won't work ! 137: * on really old Pentiums (which won't have PCIe anyway, so this is ! 138: * something of a moot point). ! 139: */ ! 140: ! 141: /** ! 142: * Read QIB7322 qword register ! 143: * ! 144: * @v qib7322 QIB7322 device ! 145: * @v dwords Register buffer to read into ! 146: * @v offset Register offset ! 147: */ ! 148: static void qib7322_readq ( struct qib7322 *qib7322, uint32_t *dwords, ! 149: unsigned long offset ) { ! 150: void *addr = ( qib7322->regs + offset ); ! 151: ! 152: __asm__ __volatile__ ( "movq (%1), %%mm0\n\t" ! 153: "movq %%mm0, (%0)\n\t" ! 154: : : "r" ( dwords ), "r" ( addr ) : "memory" ); ! 155: ! 156: DBGIO ( "[%08lx] => %08x%08x\n", ! 157: virt_to_phys ( addr ), dwords[1], dwords[0] ); ! 158: } ! 159: #define qib7322_readq( _qib7322, _ptr, _offset ) \ ! 160: qib7322_readq ( (_qib7322), (_ptr)->u.dwords, (_offset) ) ! 161: #define qib7322_readq_array8b( _qib7322, _ptr, _offset, _idx ) \ ! 162: qib7322_readq ( (_qib7322), (_ptr), ( (_offset) + ( (_idx) * 8 ) ) ) ! 163: #define qib7322_readq_array64k( _qib7322, _ptr, _offset, _idx ) \ ! 164: qib7322_readq ( (_qib7322), (_ptr), ( (_offset) + ( (_idx) * 65536 ) ) ) ! 165: #define qib7322_readq_port( _qib7322, _ptr, _offset, _port ) \ ! 166: qib7322_readq ( (_qib7322), (_ptr), ( (_offset) + ( (_port) * 4096 ) ) ) ! 167: ! 168: /** ! 169: * Write QIB7322 qword register ! 170: * ! 171: * @v qib7322 QIB7322 device ! 172: * @v dwords Register buffer to write ! 173: * @v offset Register offset ! 174: */ ! 175: static void qib7322_writeq ( struct qib7322 *qib7322, const uint32_t *dwords, ! 176: unsigned long offset ) { ! 177: void *addr = ( qib7322->regs + offset ); ! 178: ! 179: DBGIO ( "[%08lx] <= %08x%08x\n", ! 180: virt_to_phys ( addr ), dwords[1], dwords[0] ); ! 181: ! 182: __asm__ __volatile__ ( "movq (%0), %%mm0\n\t" ! 183: "movq %%mm0, (%1)\n\t" ! 184: : : "r" ( dwords ), "r" ( addr ) : "memory" ); ! 185: } ! 186: #define qib7322_writeq( _qib7322, _ptr, _offset ) \ ! 187: qib7322_writeq ( (_qib7322), (_ptr)->u.dwords, (_offset) ) ! 188: #define qib7322_writeq_array8b( _qib7322, _ptr, _offset, _idx ) \ ! 189: qib7322_writeq ( (_qib7322), (_ptr), ( (_offset) + ( (_idx) * 8 ) ) ) ! 190: #define qib7322_writeq_array64k( _qib7322, _ptr, _offset, _idx ) \ ! 191: qib7322_writeq ( (_qib7322), (_ptr), ( (_offset) + ( (_idx) * 65536 ) )) ! 192: #define qib7322_writeq_port( _qib7322, _ptr, _offset, _port ) \ ! 193: qib7322_writeq ( (_qib7322), (_ptr), ( (_offset) + ( (_port) * 4096 ) )) ! 194: ! 195: /** ! 196: * Write QIB7322 dword register ! 197: * ! 198: * @v qib7322 QIB7322 device ! 199: * @v dword Value to write ! 200: * @v offset Register offset ! 201: */ ! 202: static void qib7322_writel ( struct qib7322 *qib7322, uint32_t dword, ! 203: unsigned long offset ) { ! 204: writel ( dword, ( qib7322->regs + offset ) ); ! 205: } ! 206: ! 207: /*************************************************************************** ! 208: * ! 209: * Link state management ! 210: * ! 211: *************************************************************************** ! 212: */ ! 213: ! 214: /** ! 215: * Textual representation of link state ! 216: * ! 217: * @v link_state Link state ! 218: * @ret link_text Link state text ! 219: */ ! 220: static const char * qib7322_link_state_text ( unsigned int link_state ) { ! 221: switch ( link_state ) { ! 222: case QIB7322_LINK_STATE_DOWN: return "DOWN"; ! 223: case QIB7322_LINK_STATE_INIT: return "INIT"; ! 224: case QIB7322_LINK_STATE_ARM: return "ARM"; ! 225: case QIB7322_LINK_STATE_ACTIVE: return "ACTIVE"; ! 226: case QIB7322_LINK_STATE_ACT_DEFER: return "ACT_DEFER"; ! 227: default: return "UNKNOWN"; ! 228: } ! 229: } ! 230: ! 231: /** ! 232: * Handle link state change ! 233: * ! 234: * @v qib7322 QIB7322 device ! 235: */ ! 236: static void qib7322_link_state_changed ( struct ib_device *ibdev ) { ! 237: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 238: struct QIB_7322_IBCStatusA_0 ibcstatusa; ! 239: struct QIB_7322_EXTCtrl extctrl; ! 240: unsigned int port = ( ibdev->port - QIB7322_PORT_BASE ); ! 241: unsigned int link_training_state; ! 242: unsigned int link_state; ! 243: unsigned int link_width; ! 244: unsigned int link_speed; ! 245: unsigned int link_speed_qdr; ! 246: unsigned int green; ! 247: unsigned int yellow; ! 248: ! 249: /* Read link state */ ! 250: qib7322_readq_port ( qib7322, &ibcstatusa, ! 251: QIB_7322_IBCStatusA_0_offset, port ); ! 252: link_training_state = BIT_GET ( &ibcstatusa, LinkTrainingState ); ! 253: link_state = BIT_GET ( &ibcstatusa, LinkState ); ! 254: link_width = BIT_GET ( &ibcstatusa, LinkWidthActive ); ! 255: link_speed = BIT_GET ( &ibcstatusa, LinkSpeedActive ); ! 256: link_speed_qdr = BIT_GET ( &ibcstatusa, LinkSpeedQDR ); ! 257: DBGC ( qib7322, "QIB7322 %p port %d training state %#x link state %s " ! 258: "(%s %s)\n", qib7322, port, link_training_state, ! 259: qib7322_link_state_text ( link_state ), ! 260: ( link_speed_qdr ? "QDR" : ( link_speed ? "DDR" : "SDR" ) ), ! 261: ( link_width ? "x4" : "x1" ) ); ! 262: ! 263: /* Set LEDs according to link state */ ! 264: qib7322_readq ( qib7322, &extctrl, QIB_7322_EXTCtrl_offset ); ! 265: green = ( ( link_state >= QIB7322_LINK_STATE_INIT ) ? 1 : 0 ); ! 266: yellow = ( ( link_state >= QIB7322_LINK_STATE_ACTIVE ) ? 1 : 0 ); ! 267: if ( port == 0 ) { ! 268: BIT_SET ( &extctrl, LEDPort0GreenOn, green ); ! 269: BIT_SET ( &extctrl, LEDPort0YellowOn, yellow ); ! 270: } else { ! 271: BIT_SET ( &extctrl, LEDPort1GreenOn, green ); ! 272: BIT_SET ( &extctrl, LEDPort1YellowOn, yellow ); ! 273: } ! 274: qib7322_writeq ( qib7322, &extctrl, QIB_7322_EXTCtrl_offset ); ! 275: ! 276: /* Notify Infiniband core of link state change */ ! 277: ibdev->port_state = ( link_state + 1 ); ! 278: ibdev->link_width_active = ! 279: ( link_width ? IB_LINK_WIDTH_4X : IB_LINK_WIDTH_1X ); ! 280: ibdev->link_speed_active = ! 281: ( link_speed ? IB_LINK_SPEED_DDR : IB_LINK_SPEED_SDR ); ! 282: ib_link_state_changed ( ibdev ); ! 283: } ! 284: ! 285: /** ! 286: * Wait for link state change to take effect ! 287: * ! 288: * @v ibdev Infiniband device ! 289: * @v new_link_state Expected link state ! 290: * @ret rc Return status code ! 291: */ ! 292: static int qib7322_link_state_check ( struct ib_device *ibdev, ! 293: unsigned int new_link_state ) { ! 294: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 295: struct QIB_7322_IBCStatusA_0 ibcstatusa; ! 296: unsigned int port = ( ibdev->port - QIB7322_PORT_BASE ); ! 297: unsigned int link_state; ! 298: unsigned int i; ! 299: ! 300: for ( i = 0 ; i < QIB7322_LINK_STATE_MAX_WAIT_US ; i++ ) { ! 301: qib7322_readq_port ( qib7322, &ibcstatusa, ! 302: QIB_7322_IBCStatusA_0_offset, port ); ! 303: link_state = BIT_GET ( &ibcstatusa, LinkState ); ! 304: if ( link_state == new_link_state ) ! 305: return 0; ! 306: udelay ( 1 ); ! 307: } ! 308: ! 309: DBGC ( qib7322, "QIB7322 %p port %d timed out waiting for link state " ! 310: "%s\n", qib7322, port, qib7322_link_state_text ( link_state ) ); ! 311: return -ETIMEDOUT; ! 312: } ! 313: ! 314: /** ! 315: * Set port information ! 316: * ! 317: * @v ibdev Infiniband device ! 318: * @v mad Set port information MAD ! 319: */ ! 320: static int qib7322_set_port_info ( struct ib_device *ibdev, ! 321: union ib_mad *mad ) { ! 322: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 323: struct ib_port_info *port_info = &mad->smp.smp_data.port_info; ! 324: struct QIB_7322_IBCCtrlA_0 ibcctrla; ! 325: unsigned int port = ( ibdev->port - QIB7322_PORT_BASE ); ! 326: unsigned int port_state; ! 327: unsigned int link_state; ! 328: ! 329: /* Set new link state */ ! 330: port_state = ( port_info->link_speed_supported__port_state & 0xf ); ! 331: if ( port_state ) { ! 332: link_state = ( port_state - 1 ); ! 333: DBGC ( qib7322, "QIB7322 %p set link state to %s (%x)\n", ! 334: qib7322, qib7322_link_state_text ( link_state ), ! 335: link_state ); ! 336: qib7322_readq_port ( qib7322, &ibcctrla, ! 337: QIB_7322_IBCCtrlA_0_offset, port ); ! 338: BIT_SET ( &ibcctrla, LinkCmd, link_state ); ! 339: qib7322_writeq_port ( qib7322, &ibcctrla, ! 340: QIB_7322_IBCCtrlA_0_offset, port ); ! 341: ! 342: /* Wait for link state change to take effect. Ignore ! 343: * errors; the current link state will be returned via ! 344: * the GetResponse MAD. ! 345: */ ! 346: qib7322_link_state_check ( ibdev, link_state ); ! 347: } ! 348: ! 349: /* Detect and report link state change */ ! 350: qib7322_link_state_changed ( ibdev ); ! 351: ! 352: return 0; ! 353: } ! 354: ! 355: /** ! 356: * Set partition key table ! 357: * ! 358: * @v ibdev Infiniband device ! 359: * @v mad Set partition key table MAD ! 360: */ ! 361: static int qib7322_set_pkey_table ( struct ib_device *ibdev __unused, ! 362: union ib_mad *mad __unused ) { ! 363: /* Nothing to do */ ! 364: return 0; ! 365: } ! 366: ! 367: /*************************************************************************** ! 368: * ! 369: * Context allocation ! 370: * ! 371: *************************************************************************** ! 372: */ ! 373: ! 374: /** ! 375: * Allocate a context and set queue pair number ! 376: * ! 377: * @v ibdev Infiniband device ! 378: * @v qp Queue pair ! 379: * @ret rc Return status code ! 380: */ ! 381: static int qib7322_alloc_ctx ( struct ib_device *ibdev, ! 382: struct ib_queue_pair *qp ) { ! 383: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 384: unsigned int port = ( ibdev->port - QIB7322_PORT_BASE ); ! 385: unsigned int ctx; ! 386: ! 387: for ( ctx = port ; ctx < QIB7322_NUM_CONTEXTS ; ctx += 2 ) { ! 388: ! 389: if ( ! qib7322->used_ctx[ctx] ) { ! 390: qib7322->used_ctx[ctx] = 1; ! 391: qp->qpn = ( ctx & ~0x01 ); ! 392: DBGC2 ( qib7322, "QIB7322 %p port %d QPN %ld is CTX " ! 393: "%d\n", qib7322, port, qp->qpn, ctx ); ! 394: return 0; ! 395: } ! 396: } ! 397: ! 398: DBGC ( qib7322, "QIB7322 %p port %d out of available contexts\n", ! 399: qib7322, port ); ! 400: return -ENOENT; ! 401: } ! 402: ! 403: /** ! 404: * Get queue pair context number ! 405: * ! 406: * @v ibdev Infiniband device ! 407: * @v qp Queue pair ! 408: * @ret ctx Context index ! 409: */ ! 410: static unsigned int qib7322_ctx ( struct ib_device *ibdev, ! 411: struct ib_queue_pair *qp ) { ! 412: return ( qp->qpn + ( ibdev->port - QIB7322_PORT_BASE ) ); ! 413: } ! 414: ! 415: /** ! 416: * Free a context ! 417: * ! 418: * @v qib7322 QIB7322 device ! 419: * @v ctx Context index ! 420: */ ! 421: static void qib7322_free_ctx ( struct ib_device *ibdev, ! 422: struct ib_queue_pair *qp ) { ! 423: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 424: unsigned int port = ( ibdev->port - QIB7322_PORT_BASE ); ! 425: unsigned int ctx = qib7322_ctx ( ibdev, qp ); ! 426: ! 427: qib7322->used_ctx[ctx] = 0; ! 428: DBGC2 ( qib7322, "QIB7322 %p port %d CTX %d freed\n", ! 429: qib7322, port, ctx ); ! 430: } ! 431: ! 432: /*************************************************************************** ! 433: * ! 434: * Send datapath ! 435: * ! 436: *************************************************************************** ! 437: */ ! 438: ! 439: /** Send buffer toggle bit ! 440: * ! 441: * We encode send buffers as 15 bits of send buffer index plus a ! 442: * single bit which should match the "check" bit in the SendBufAvail ! 443: * array. ! 444: */ ! 445: #define QIB7322_SEND_BUF_TOGGLE 0x8000 ! 446: ! 447: /** ! 448: * Create send buffer set ! 449: * ! 450: * @v qib7322 QIB7322 device ! 451: * @v base Send buffer base offset ! 452: * @v size Send buffer size ! 453: * @v start Index of first send buffer ! 454: * @v count Number of send buffers ! 455: * @ret send_bufs Send buffer set ! 456: */ ! 457: static struct qib7322_send_buffers * ! 458: qib7322_create_send_bufs ( struct qib7322 *qib7322, unsigned long base, ! 459: unsigned int size, unsigned int start, ! 460: unsigned int count ) { ! 461: struct qib7322_send_buffers *send_bufs; ! 462: unsigned int i; ! 463: ! 464: /* Allocate send buffer set */ ! 465: send_bufs = zalloc ( sizeof ( *send_bufs ) + ! 466: ( count * sizeof ( send_bufs->avail[0] ) ) ); ! 467: if ( ! send_bufs ) ! 468: return NULL; ! 469: ! 470: /* Populate send buffer set */ ! 471: send_bufs->base = base; ! 472: send_bufs->size = size; ! 473: send_bufs->start = start; ! 474: send_bufs->count = count; ! 475: for ( i = 0 ; i < count ; i++ ) ! 476: send_bufs->avail[i] = ( start + i ); ! 477: ! 478: DBGC2 ( qib7322, "QIB7322 %p send buffer set %p [%d,%d] at %lx\n", ! 479: qib7322, send_bufs, start, ( start + count - 1 ), ! 480: send_bufs->base ); ! 481: ! 482: return send_bufs; ! 483: } ! 484: ! 485: /** ! 486: * Destroy send buffer set ! 487: * ! 488: * @v qib7322 QIB7322 device ! 489: * @v send_bufs Send buffer set ! 490: */ ! 491: static void ! 492: qib7322_destroy_send_bufs ( struct qib7322 *qib7322 __unused, ! 493: struct qib7322_send_buffers *send_bufs ) { ! 494: free ( send_bufs ); ! 495: } ! 496: ! 497: /** ! 498: * Allocate a send buffer ! 499: * ! 500: * @v qib7322 QIB7322 device ! 501: * @v send_bufs Send buffer set ! 502: * @ret send_buf Send buffer, or negative error ! 503: */ ! 504: static int qib7322_alloc_send_buf ( struct qib7322 *qib7322, ! 505: struct qib7322_send_buffers *send_bufs ) { ! 506: unsigned int used; ! 507: unsigned int mask; ! 508: unsigned int send_buf; ! 509: ! 510: used = ( send_bufs->cons - send_bufs->prod ); ! 511: if ( used >= send_bufs->count ) { ! 512: DBGC ( qib7322, "QIB7322 %p send buffer set %p out of " ! 513: "buffers\n", qib7322, send_bufs ); ! 514: return -ENOBUFS; ! 515: } ! 516: ! 517: mask = ( send_bufs->count - 1 ); ! 518: send_buf = send_bufs->avail[ send_bufs->cons++ & mask ]; ! 519: send_buf ^= QIB7322_SEND_BUF_TOGGLE; ! 520: return send_buf; ! 521: } ! 522: ! 523: /** ! 524: * Free a send buffer ! 525: * ! 526: * @v qib7322 QIB7322 device ! 527: * @v send_bufs Send buffer set ! 528: * @v send_buf Send buffer ! 529: */ ! 530: static void qib7322_free_send_buf ( struct qib7322 *qib7322 __unused, ! 531: struct qib7322_send_buffers *send_bufs, ! 532: unsigned int send_buf ) { ! 533: unsigned int mask; ! 534: ! 535: mask = ( send_bufs->count - 1 ); ! 536: send_bufs->avail[ send_bufs->prod++ & mask ] = send_buf; ! 537: } ! 538: ! 539: /** ! 540: * Check to see if send buffer is in use ! 541: * ! 542: * @v qib7322 QIB7322 device ! 543: * @v send_buf Send buffer ! 544: * @ret in_use Send buffer is in use ! 545: */ ! 546: static int qib7322_send_buf_in_use ( struct qib7322 *qib7322, ! 547: unsigned int send_buf ) { ! 548: unsigned int send_idx; ! 549: unsigned int send_check; ! 550: unsigned int inusecheck; ! 551: unsigned int inuse; ! 552: unsigned int check; ! 553: ! 554: send_idx = ( send_buf & ~QIB7322_SEND_BUF_TOGGLE ); ! 555: send_check = ( !! ( send_buf & QIB7322_SEND_BUF_TOGGLE ) ); ! 556: inusecheck = BIT_GET ( qib7322->sendbufavail, InUseCheck[send_idx] ); ! 557: inuse = ( !! ( inusecheck & 0x02 ) ); ! 558: check = ( !! ( inusecheck & 0x01 ) ); ! 559: return ( inuse || ( check != send_check ) ); ! 560: } ! 561: ! 562: /** ! 563: * Calculate starting offset for send buffer ! 564: * ! 565: * @v qib7322 QIB7322 device ! 566: * @v send_buf Send buffer ! 567: * @ret offset Starting offset ! 568: */ ! 569: static unsigned long ! 570: qib7322_send_buffer_offset ( struct qib7322 *qib7322 __unused, ! 571: struct qib7322_send_buffers *send_bufs, ! 572: unsigned int send_buf ) { ! 573: unsigned int index; ! 574: ! 575: index = ( ( send_buf & ~QIB7322_SEND_BUF_TOGGLE ) - send_bufs->start ); ! 576: return ( send_bufs->base + ( index * send_bufs->size ) ); ! 577: } ! 578: ! 579: /** ! 580: * Create send work queue ! 581: * ! 582: * @v ibdev Infiniband device ! 583: * @v qp Queue pair ! 584: */ ! 585: static int qib7322_create_send_wq ( struct ib_device *ibdev, ! 586: struct ib_queue_pair *qp ) { ! 587: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 588: struct ib_work_queue *wq = &qp->send; ! 589: struct qib7322_send_work_queue *qib7322_wq = ib_wq_get_drvdata ( wq ); ! 590: unsigned int port = ( ibdev->port - QIB7322_PORT_BASE ); ! 591: ! 592: /* Select send buffer set */ ! 593: if ( qp->type == IB_QPT_SMI ) { ! 594: if ( port == 0 ) { ! 595: qib7322_wq->send_bufs = qib7322->send_bufs_vl15_port0; ! 596: } else { ! 597: qib7322_wq->send_bufs = qib7322->send_bufs_vl15_port1; ! 598: } ! 599: } else { ! 600: qib7322_wq->send_bufs = qib7322->send_bufs_small; ! 601: } ! 602: ! 603: /* Allocate space for send buffer usage list */ ! 604: qib7322_wq->used = zalloc ( qp->send.num_wqes * ! 605: sizeof ( qib7322_wq->used[0] ) ); ! 606: if ( ! qib7322_wq->used ) ! 607: return -ENOMEM; ! 608: ! 609: /* Reset work queue */ ! 610: qib7322_wq->prod = 0; ! 611: qib7322_wq->cons = 0; ! 612: ! 613: return 0; ! 614: } ! 615: ! 616: /** ! 617: * Destroy send work queue ! 618: * ! 619: * @v ibdev Infiniband device ! 620: * @v qp Queue pair ! 621: */ ! 622: static void qib7322_destroy_send_wq ( struct ib_device *ibdev __unused, ! 623: struct ib_queue_pair *qp ) { ! 624: struct ib_work_queue *wq = &qp->send; ! 625: struct qib7322_send_work_queue *qib7322_wq = ib_wq_get_drvdata ( wq ); ! 626: ! 627: free ( qib7322_wq->used ); ! 628: } ! 629: ! 630: /** ! 631: * Initialise send datapath ! 632: * ! 633: * @v qib7322 QIB7322 device ! 634: * @ret rc Return status code ! 635: */ ! 636: static int qib7322_init_send ( struct qib7322 *qib7322 ) { ! 637: struct QIB_7322_SendBufBase sendbufbase; ! 638: struct QIB_7322_SendBufAvailAddr sendbufavailaddr; ! 639: struct QIB_7322_SendCtrl sendctrl; ! 640: struct QIB_7322_SendCtrl_0 sendctrlp; ! 641: unsigned long baseaddr_smallpio; ! 642: unsigned long baseaddr_largepio; ! 643: unsigned long baseaddr_vl15_port0; ! 644: unsigned long baseaddr_vl15_port1; ! 645: int rc; ! 646: ! 647: /* Create send buffer sets */ ! 648: qib7322_readq ( qib7322, &sendbufbase, QIB_7322_SendBufBase_offset ); ! 649: baseaddr_smallpio = BIT_GET ( &sendbufbase, BaseAddr_SmallPIO ); ! 650: baseaddr_largepio = BIT_GET ( &sendbufbase, BaseAddr_LargePIO ); ! 651: baseaddr_vl15_port0 = ( baseaddr_largepio + ! 652: ( QIB7322_LARGE_SEND_BUF_SIZE * ! 653: QIB7322_LARGE_SEND_BUF_COUNT ) ); ! 654: baseaddr_vl15_port1 = ( baseaddr_vl15_port0 + ! 655: QIB7322_VL15_PORT0_SEND_BUF_SIZE ); ! 656: qib7322->send_bufs_small = ! 657: qib7322_create_send_bufs ( qib7322, baseaddr_smallpio, ! 658: QIB7322_SMALL_SEND_BUF_SIZE, ! 659: QIB7322_SMALL_SEND_BUF_START, ! 660: QIB7322_SMALL_SEND_BUF_USED ); ! 661: if ( ! qib7322->send_bufs_small ) { ! 662: rc = -ENOMEM; ! 663: goto err_create_send_bufs_small; ! 664: } ! 665: qib7322->send_bufs_vl15_port0 = ! 666: qib7322_create_send_bufs ( qib7322, baseaddr_vl15_port0, ! 667: QIB7322_VL15_PORT0_SEND_BUF_SIZE, ! 668: QIB7322_VL15_PORT0_SEND_BUF_START, ! 669: QIB7322_VL15_PORT0_SEND_BUF_COUNT ); ! 670: if ( ! qib7322->send_bufs_vl15_port0 ) { ! 671: rc = -ENOMEM; ! 672: goto err_create_send_bufs_vl15_port0; ! 673: } ! 674: qib7322->send_bufs_vl15_port1 = ! 675: qib7322_create_send_bufs ( qib7322, baseaddr_vl15_port1, ! 676: QIB7322_VL15_PORT1_SEND_BUF_SIZE, ! 677: QIB7322_VL15_PORT1_SEND_BUF_START, ! 678: QIB7322_VL15_PORT1_SEND_BUF_COUNT ); ! 679: if ( ! qib7322->send_bufs_vl15_port1 ) { ! 680: rc = -ENOMEM; ! 681: goto err_create_send_bufs_vl15_port1; ! 682: } ! 683: ! 684: /* Allocate space for the SendBufAvail array */ ! 685: qib7322->sendbufavail = malloc_dma ( sizeof ( *qib7322->sendbufavail ), ! 686: QIB7322_SENDBUFAVAIL_ALIGN ); ! 687: if ( ! qib7322->sendbufavail ) { ! 688: rc = -ENOMEM; ! 689: goto err_alloc_sendbufavail; ! 690: } ! 691: memset ( qib7322->sendbufavail, 0, sizeof ( qib7322->sendbufavail ) ); ! 692: ! 693: /* Program SendBufAvailAddr into the hardware */ ! 694: memset ( &sendbufavailaddr, 0, sizeof ( sendbufavailaddr ) ); ! 695: BIT_FILL_1 ( &sendbufavailaddr, SendBufAvailAddr, ! 696: ( virt_to_bus ( qib7322->sendbufavail ) >> 6 ) ); ! 697: qib7322_writeq ( qib7322, &sendbufavailaddr, ! 698: QIB_7322_SendBufAvailAddr_offset ); ! 699: ! 700: /* Enable sending */ ! 701: memset ( &sendctrlp, 0, sizeof ( sendctrlp ) ); ! 702: BIT_FILL_1 ( &sendctrlp, SendEnable, 1 ); ! 703: qib7322_writeq ( qib7322, &sendctrlp, QIB_7322_SendCtrl_0_offset ); ! 704: qib7322_writeq ( qib7322, &sendctrlp, QIB_7322_SendCtrl_1_offset ); ! 705: ! 706: /* Enable DMA of SendBufAvail */ ! 707: memset ( &sendctrl, 0, sizeof ( sendctrl ) ); ! 708: BIT_FILL_1 ( &sendctrl, SendBufAvailUpd, 1 ); ! 709: qib7322_writeq ( qib7322, &sendctrl, QIB_7322_SendCtrl_offset ); ! 710: ! 711: return 0; ! 712: ! 713: free_dma ( qib7322->sendbufavail, sizeof ( *qib7322->sendbufavail ) ); ! 714: err_alloc_sendbufavail: ! 715: qib7322_destroy_send_bufs ( qib7322, qib7322->send_bufs_vl15_port1 ); ! 716: err_create_send_bufs_vl15_port1: ! 717: qib7322_destroy_send_bufs ( qib7322, qib7322->send_bufs_vl15_port0 ); ! 718: err_create_send_bufs_vl15_port0: ! 719: qib7322_destroy_send_bufs ( qib7322, qib7322->send_bufs_small ); ! 720: err_create_send_bufs_small: ! 721: return rc; ! 722: } ! 723: ! 724: /** ! 725: * Shut down send datapath ! 726: * ! 727: * @v qib7322 QIB7322 device ! 728: */ ! 729: static void qib7322_fini_send ( struct qib7322 *qib7322 ) { ! 730: struct QIB_7322_SendCtrl sendctrl; ! 731: ! 732: /* Disable sending and DMA of SendBufAvail */ ! 733: memset ( &sendctrl, 0, sizeof ( sendctrl ) ); ! 734: qib7322_writeq ( qib7322, &sendctrl, QIB_7322_SendCtrl_offset ); ! 735: mb(); ! 736: ! 737: /* Ensure hardware has seen this disable */ ! 738: qib7322_readq ( qib7322, &sendctrl, QIB_7322_SendCtrl_offset ); ! 739: ! 740: free_dma ( qib7322->sendbufavail, sizeof ( *qib7322->sendbufavail ) ); ! 741: qib7322_destroy_send_bufs ( qib7322, qib7322->send_bufs_vl15_port1 ); ! 742: qib7322_destroy_send_bufs ( qib7322, qib7322->send_bufs_vl15_port0 ); ! 743: qib7322_destroy_send_bufs ( qib7322, qib7322->send_bufs_small ); ! 744: } ! 745: ! 746: /*************************************************************************** ! 747: * ! 748: * Receive datapath ! 749: * ! 750: *************************************************************************** ! 751: */ ! 752: ! 753: /** ! 754: * Create receive work queue ! 755: * ! 756: * @v ibdev Infiniband device ! 757: * @v qp Queue pair ! 758: * @ret rc Return status code ! 759: */ ! 760: static int qib7322_create_recv_wq ( struct ib_device *ibdev, ! 761: struct ib_queue_pair *qp ) { ! 762: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 763: struct ib_work_queue *wq = &qp->recv; ! 764: struct qib7322_recv_work_queue *qib7322_wq = ib_wq_get_drvdata ( wq ); ! 765: struct QIB_7322_RcvHdrAddr0 rcvhdraddr; ! 766: struct QIB_7322_RcvHdrTailAddr0 rcvhdrtailaddr; ! 767: struct QIB_7322_RcvHdrHead0 rcvhdrhead; ! 768: struct QIB_7322_scalar rcvegrindexhead; ! 769: struct QIB_7322_RcvCtrl rcvctrl; ! 770: struct QIB_7322_RcvCtrl_P rcvctrlp; ! 771: unsigned int port = ( ibdev->port - QIB7322_PORT_BASE ); ! 772: unsigned int ctx = qib7322_ctx ( ibdev, qp ); ! 773: int rc; ! 774: ! 775: /* Reset context information */ ! 776: memset ( &qib7322_wq->header_prod, 0, ! 777: sizeof ( qib7322_wq->header_prod ) ); ! 778: qib7322_wq->header_cons = 0; ! 779: qib7322_wq->eager_prod = 0; ! 780: qib7322_wq->eager_cons = 0; ! 781: ! 782: /* Allocate receive header buffer */ ! 783: qib7322_wq->header = malloc_dma ( QIB7322_RECV_HEADERS_SIZE, ! 784: QIB7322_RECV_HEADERS_ALIGN ); ! 785: if ( ! qib7322_wq->header ) { ! 786: rc = -ENOMEM; ! 787: goto err_alloc_header; ! 788: } ! 789: ! 790: /* Enable context in hardware */ ! 791: memset ( &rcvhdraddr, 0, sizeof ( rcvhdraddr ) ); ! 792: BIT_FILL_1 ( &rcvhdraddr, RcvHdrAddr, ! 793: ( virt_to_bus ( qib7322_wq->header ) >> 2 ) ); ! 794: qib7322_writeq_array8b ( qib7322, &rcvhdraddr, ! 795: QIB_7322_RcvHdrAddr0_offset, ctx ); ! 796: memset ( &rcvhdrtailaddr, 0, sizeof ( rcvhdrtailaddr ) ); ! 797: BIT_FILL_1 ( &rcvhdrtailaddr, RcvHdrTailAddr, ! 798: ( virt_to_bus ( &qib7322_wq->header_prod ) >> 2 ) ); ! 799: qib7322_writeq_array8b ( qib7322, &rcvhdrtailaddr, ! 800: QIB_7322_RcvHdrTailAddr0_offset, ctx ); ! 801: memset ( &rcvhdrhead, 0, sizeof ( rcvhdrhead ) ); ! 802: BIT_FILL_1 ( &rcvhdrhead, counter, 1 ); ! 803: qib7322_writeq_array64k ( qib7322, &rcvhdrhead, ! 804: QIB_7322_RcvHdrHead0_offset, ctx ); ! 805: memset ( &rcvegrindexhead, 0, sizeof ( rcvegrindexhead ) ); ! 806: BIT_FILL_1 ( &rcvegrindexhead, Value, 1 ); ! 807: qib7322_writeq_array64k ( qib7322, &rcvegrindexhead, ! 808: QIB_7322_RcvEgrIndexHead0_offset, ctx ); ! 809: qib7322_readq_port ( qib7322, &rcvctrlp, ! 810: QIB_7322_RcvCtrl_0_offset, port ); ! 811: BIT_SET ( &rcvctrlp, ContextEnable[ctx], 1 ); ! 812: qib7322_writeq_port ( qib7322, &rcvctrlp, ! 813: QIB_7322_RcvCtrl_0_offset, port ); ! 814: qib7322_readq ( qib7322, &rcvctrl, QIB_7322_RcvCtrl_offset ); ! 815: BIT_SET ( &rcvctrl, IntrAvail[ctx], 1 ); ! 816: qib7322_writeq ( qib7322, &rcvctrl, QIB_7322_RcvCtrl_offset ); ! 817: ! 818: DBGC ( qib7322, "QIB7322 %p port %d QPN %ld CTX %d hdrs [%lx,%lx) prod " ! 819: "%lx\n", qib7322, port, qp->qpn, ctx, ! 820: virt_to_bus ( qib7322_wq->header ), ! 821: ( virt_to_bus ( qib7322_wq->header ) ! 822: + QIB7322_RECV_HEADERS_SIZE ), ! 823: virt_to_bus ( &qib7322_wq->header_prod ) ); ! 824: return 0; ! 825: ! 826: free_dma ( qib7322_wq->header, QIB7322_RECV_HEADERS_SIZE ); ! 827: err_alloc_header: ! 828: return rc; ! 829: } ! 830: ! 831: /** ! 832: * Destroy receive work queue ! 833: * ! 834: * @v ibdev Infiniband device ! 835: * @v qp Queue pair ! 836: */ ! 837: static void qib7322_destroy_recv_wq ( struct ib_device *ibdev, ! 838: struct ib_queue_pair *qp ) { ! 839: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 840: struct ib_work_queue *wq = &qp->recv; ! 841: struct qib7322_recv_work_queue *qib7322_wq = ib_wq_get_drvdata ( wq ); ! 842: struct QIB_7322_RcvCtrl rcvctrl; ! 843: struct QIB_7322_RcvCtrl_P rcvctrlp; ! 844: unsigned int port = ( ibdev->port - QIB7322_PORT_BASE ); ! 845: unsigned int ctx = qib7322_ctx ( ibdev, qp ); ! 846: ! 847: /* Disable context in hardware */ ! 848: qib7322_readq_port ( qib7322, &rcvctrlp, ! 849: QIB_7322_RcvCtrl_0_offset, port ); ! 850: BIT_SET ( &rcvctrlp, ContextEnable[ctx], 0 ); ! 851: qib7322_writeq_port ( qib7322, &rcvctrlp, ! 852: QIB_7322_RcvCtrl_0_offset, port ); ! 853: qib7322_readq ( qib7322, &rcvctrl, QIB_7322_RcvCtrl_offset ); ! 854: BIT_SET ( &rcvctrl, IntrAvail[ctx], 0 ); ! 855: qib7322_writeq ( qib7322, &rcvctrl, QIB_7322_RcvCtrl_offset ); ! 856: ! 857: /* Make sure the hardware has seen that the context is disabled */ ! 858: qib7322_readq ( qib7322, &rcvctrl, QIB_7322_RcvCtrl_offset ); ! 859: mb(); ! 860: ! 861: /* Free headers ring */ ! 862: free_dma ( qib7322_wq->header, QIB7322_RECV_HEADERS_SIZE ); ! 863: } ! 864: ! 865: /** ! 866: * Initialise receive datapath ! 867: * ! 868: * @v qib7322 QIB7322 device ! 869: * @ret rc Return status code ! 870: */ ! 871: static int qib7322_init_recv ( struct qib7322 *qib7322 ) { ! 872: struct QIB_7322_RcvCtrl rcvctrl; ! 873: struct QIB_7322_RcvCtrl_0 rcvctrlp; ! 874: struct QIB_7322_RcvQPMapTableA_0 rcvqpmaptablea0; ! 875: struct QIB_7322_RcvQPMapTableB_0 rcvqpmaptableb0; ! 876: struct QIB_7322_RcvQPMapTableA_1 rcvqpmaptablea1; ! 877: struct QIB_7322_RcvQPMapTableB_1 rcvqpmaptableb1; ! 878: struct QIB_7322_RcvQPMulticastContext_0 rcvqpmcastctx0; ! 879: struct QIB_7322_RcvQPMulticastContext_1 rcvqpmcastctx1; ! 880: struct QIB_7322_scalar rcvegrbase; ! 881: struct QIB_7322_scalar rcvhdrentsize; ! 882: struct QIB_7322_scalar rcvhdrcnt; ! 883: struct QIB_7322_RcvBTHQP_0 rcvbthqp; ! 884: struct QIB_7322_RxCreditVL0_0 rxcreditvl; ! 885: unsigned int contextcfg; ! 886: unsigned long egrbase; ! 887: unsigned int eager_array_size_kernel; ! 888: unsigned int eager_array_size_user; ! 889: unsigned int ctx; ! 890: ! 891: /* Select configuration based on number of contexts */ ! 892: switch ( QIB7322_NUM_CONTEXTS ) { ! 893: case 6: ! 894: contextcfg = QIB7322_CONTEXTCFG_6CTX; ! 895: eager_array_size_kernel = QIB7322_EAGER_ARRAY_SIZE_6CTX_KERNEL; ! 896: eager_array_size_user = QIB7322_EAGER_ARRAY_SIZE_6CTX_USER; ! 897: break; ! 898: case 10: ! 899: contextcfg = QIB7322_CONTEXTCFG_10CTX; ! 900: eager_array_size_kernel = QIB7322_EAGER_ARRAY_SIZE_10CTX_KERNEL; ! 901: eager_array_size_user = QIB7322_EAGER_ARRAY_SIZE_10CTX_USER; ! 902: break; ! 903: case 18: ! 904: contextcfg = QIB7322_CONTEXTCFG_18CTX; ! 905: eager_array_size_kernel = QIB7322_EAGER_ARRAY_SIZE_18CTX_KERNEL; ! 906: eager_array_size_user = QIB7322_EAGER_ARRAY_SIZE_18CTX_USER; ! 907: break; ! 908: default: ! 909: linker_assert ( 0, invalid_QIB7322_NUM_CONTEXTS ); ! 910: return -EINVAL; ! 911: } ! 912: ! 913: /* Configure number of contexts */ ! 914: memset ( &rcvctrl, 0, sizeof ( rcvctrl ) ); ! 915: BIT_FILL_2 ( &rcvctrl, ! 916: TailUpd, 1, ! 917: ContextCfg, contextcfg ); ! 918: qib7322_writeq ( qib7322, &rcvctrl, QIB_7322_RcvCtrl_offset ); ! 919: ! 920: /* Map QPNs to contexts */ ! 921: memset ( &rcvctrlp, 0, sizeof ( rcvctrlp ) ); ! 922: BIT_FILL_3 ( &rcvctrlp, ! 923: RcvIBPortEnable, 1, ! 924: RcvQPMapEnable, 1, ! 925: RcvPartitionKeyDisable, 1 ); ! 926: qib7322_writeq ( qib7322, &rcvctrlp, QIB_7322_RcvCtrl_0_offset ); ! 927: qib7322_writeq ( qib7322, &rcvctrlp, QIB_7322_RcvCtrl_1_offset ); ! 928: memset ( &rcvqpmaptablea0, 0, sizeof ( rcvqpmaptablea0 ) ); ! 929: BIT_FILL_6 ( &rcvqpmaptablea0, ! 930: RcvQPMapContext0, 0, ! 931: RcvQPMapContext1, 2, ! 932: RcvQPMapContext2, 4, ! 933: RcvQPMapContext3, 6, ! 934: RcvQPMapContext4, 8, ! 935: RcvQPMapContext5, 10 ); ! 936: qib7322_writeq ( qib7322, &rcvqpmaptablea0, ! 937: QIB_7322_RcvQPMapTableA_0_offset ); ! 938: memset ( &rcvqpmaptableb0, 0, sizeof ( rcvqpmaptableb0 ) ); ! 939: BIT_FILL_3 ( &rcvqpmaptableb0, ! 940: RcvQPMapContext6, 12, ! 941: RcvQPMapContext7, 14, ! 942: RcvQPMapContext8, 16 ); ! 943: qib7322_writeq ( qib7322, &rcvqpmaptableb0, ! 944: QIB_7322_RcvQPMapTableB_0_offset ); ! 945: memset ( &rcvqpmaptablea1, 0, sizeof ( rcvqpmaptablea1 ) ); ! 946: BIT_FILL_6 ( &rcvqpmaptablea1, ! 947: RcvQPMapContext0, 1, ! 948: RcvQPMapContext1, 3, ! 949: RcvQPMapContext2, 5, ! 950: RcvQPMapContext3, 7, ! 951: RcvQPMapContext4, 9, ! 952: RcvQPMapContext5, 11 ); ! 953: qib7322_writeq ( qib7322, &rcvqpmaptablea1, ! 954: QIB_7322_RcvQPMapTableA_1_offset ); ! 955: memset ( &rcvqpmaptableb1, 0, sizeof ( rcvqpmaptableb1 ) ); ! 956: BIT_FILL_3 ( &rcvqpmaptableb1, ! 957: RcvQPMapContext6, 13, ! 958: RcvQPMapContext7, 15, ! 959: RcvQPMapContext8, 17 ); ! 960: qib7322_writeq ( qib7322, &rcvqpmaptableb1, ! 961: QIB_7322_RcvQPMapTableB_1_offset ); ! 962: ! 963: /* Map multicast QPNs to contexts */ ! 964: memset ( &rcvqpmcastctx0, 0, sizeof ( rcvqpmcastctx0 ) ); ! 965: BIT_FILL_1 ( &rcvqpmcastctx0, RcvQpMcContext, 0 ); ! 966: qib7322_writeq ( qib7322, &rcvqpmcastctx0, ! 967: QIB_7322_RcvQPMulticastContext_0_offset ); ! 968: memset ( &rcvqpmcastctx1, 0, sizeof ( rcvqpmcastctx1 ) ); ! 969: BIT_FILL_1 ( &rcvqpmcastctx1, RcvQpMcContext, 1 ); ! 970: qib7322_writeq ( qib7322, &rcvqpmcastctx1, ! 971: QIB_7322_RcvQPMulticastContext_1_offset ); ! 972: ! 973: /* Configure receive header buffer sizes */ ! 974: memset ( &rcvhdrcnt, 0, sizeof ( rcvhdrcnt ) ); ! 975: BIT_FILL_1 ( &rcvhdrcnt, Value, QIB7322_RECV_HEADER_COUNT ); ! 976: qib7322_writeq ( qib7322, &rcvhdrcnt, QIB_7322_RcvHdrCnt_offset ); ! 977: memset ( &rcvhdrentsize, 0, sizeof ( rcvhdrentsize ) ); ! 978: BIT_FILL_1 ( &rcvhdrentsize, Value, ( QIB7322_RECV_HEADER_SIZE >> 2 ) ); ! 979: qib7322_writeq ( qib7322, &rcvhdrentsize, ! 980: QIB_7322_RcvHdrEntSize_offset ); ! 981: ! 982: /* Calculate eager array start addresses for each context */ ! 983: qib7322_readq ( qib7322, &rcvegrbase, QIB_7322_RcvEgrBase_offset ); ! 984: egrbase = BIT_GET ( &rcvegrbase, Value ); ! 985: for ( ctx = 0 ; ctx < QIB7322_MAX_PORTS ; ctx++ ) { ! 986: qib7322->recv_wq[ctx].eager_array = egrbase; ! 987: qib7322->recv_wq[ctx].eager_entries = eager_array_size_kernel; ! 988: egrbase += ( eager_array_size_kernel * ! 989: sizeof ( struct QIB_7322_RcvEgr ) ); ! 990: } ! 991: for ( ; ctx < QIB7322_NUM_CONTEXTS ; ctx++ ) { ! 992: qib7322->recv_wq[ctx].eager_array = egrbase; ! 993: qib7322->recv_wq[ctx].eager_entries = eager_array_size_user; ! 994: egrbase += ( eager_array_size_user * ! 995: sizeof ( struct QIB_7322_RcvEgr ) ); ! 996: } ! 997: for ( ctx = 0 ; ctx < QIB7322_NUM_CONTEXTS ; ctx++ ) { ! 998: DBGC ( qib7322, "QIB7322 %p CTX %d eager array at %lx (%d " ! 999: "entries)\n", qib7322, ctx, ! 1000: qib7322->recv_wq[ctx].eager_array, ! 1001: qib7322->recv_wq[ctx].eager_entries ); ! 1002: } ! 1003: ! 1004: /* Set the BTH QP for Infinipath packets to an unused value */ ! 1005: memset ( &rcvbthqp, 0, sizeof ( rcvbthqp ) ); ! 1006: BIT_FILL_1 ( &rcvbthqp, RcvBTHQP, QIB7322_QP_IDETH ); ! 1007: qib7322_writeq ( qib7322, &rcvbthqp, QIB_7322_RcvBTHQP_0_offset ); ! 1008: qib7322_writeq ( qib7322, &rcvbthqp, QIB_7322_RcvBTHQP_1_offset ); ! 1009: ! 1010: /* Assign initial credits */ ! 1011: memset ( &rxcreditvl, 0, sizeof ( rxcreditvl ) ); ! 1012: BIT_FILL_1 ( &rxcreditvl, RxMaxCreditVL, QIB7322_MAX_CREDITS_VL0 ); ! 1013: qib7322_writeq_array8b ( qib7322, &rxcreditvl, ! 1014: QIB_7322_RxCreditVL0_0_offset, 0 ); ! 1015: qib7322_writeq_array8b ( qib7322, &rxcreditvl, ! 1016: QIB_7322_RxCreditVL0_1_offset, 0 ); ! 1017: BIT_FILL_1 ( &rxcreditvl, RxMaxCreditVL, QIB7322_MAX_CREDITS_VL15 ); ! 1018: qib7322_writeq_array8b ( qib7322, &rxcreditvl, ! 1019: QIB_7322_RxCreditVL0_0_offset, 15 ); ! 1020: qib7322_writeq_array8b ( qib7322, &rxcreditvl, ! 1021: QIB_7322_RxCreditVL0_1_offset, 15 ); ! 1022: ! 1023: return 0; ! 1024: } ! 1025: ! 1026: /** ! 1027: * Shut down receive datapath ! 1028: * ! 1029: * @v qib7322 QIB7322 device ! 1030: */ ! 1031: static void qib7322_fini_recv ( struct qib7322 *qib7322 __unused ) { ! 1032: /* Nothing to do; all contexts were already disabled when the ! 1033: * queue pairs were destroyed ! 1034: */ ! 1035: } ! 1036: ! 1037: /*************************************************************************** ! 1038: * ! 1039: * Completion queue operations ! 1040: * ! 1041: *************************************************************************** ! 1042: */ ! 1043: ! 1044: /** ! 1045: * Create completion queue ! 1046: * ! 1047: * @v ibdev Infiniband device ! 1048: * @v cq Completion queue ! 1049: * @ret rc Return status code ! 1050: */ ! 1051: static int qib7322_create_cq ( struct ib_device *ibdev, ! 1052: struct ib_completion_queue *cq ) { ! 1053: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 1054: static int cqn; ! 1055: ! 1056: /* The hardware has no concept of completion queues. We ! 1057: * simply use the association between CQs and WQs (already ! 1058: * handled by the IB core) to decide which WQs to poll. ! 1059: * ! 1060: * We do set a CQN, just to avoid confusing debug messages ! 1061: * from the IB core. ! 1062: */ ! 1063: cq->cqn = ++cqn; ! 1064: DBGC ( qib7322, "QIB7322 %p CQN %ld created\n", qib7322, cq->cqn ); ! 1065: ! 1066: return 0; ! 1067: } ! 1068: ! 1069: /** ! 1070: * Destroy completion queue ! 1071: * ! 1072: * @v ibdev Infiniband device ! 1073: * @v cq Completion queue ! 1074: */ ! 1075: static void qib7322_destroy_cq ( struct ib_device *ibdev, ! 1076: struct ib_completion_queue *cq ) { ! 1077: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 1078: ! 1079: /* Nothing to do */ ! 1080: DBGC ( qib7322, "QIB7322 %p CQN %ld destroyed\n", qib7322, cq->cqn ); ! 1081: } ! 1082: ! 1083: /*************************************************************************** ! 1084: * ! 1085: * Queue pair operations ! 1086: * ! 1087: *************************************************************************** ! 1088: */ ! 1089: ! 1090: /** ! 1091: * Create queue pair ! 1092: * ! 1093: * @v ibdev Infiniband device ! 1094: * @v qp Queue pair ! 1095: * @ret rc Return status code ! 1096: */ ! 1097: static int qib7322_create_qp ( struct ib_device *ibdev, ! 1098: struct ib_queue_pair *qp ) { ! 1099: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 1100: unsigned int ctx; ! 1101: int rc; ! 1102: ! 1103: /* Allocate a context and QPN */ ! 1104: if ( ( rc = qib7322_alloc_ctx ( ibdev, qp ) ) != 0 ) ! 1105: goto err_alloc_ctx; ! 1106: ctx = qib7322_ctx ( ibdev, qp ); ! 1107: ! 1108: /* Set work-queue private data pointers */ ! 1109: ib_wq_set_drvdata ( &qp->send, &qib7322->send_wq[ctx] ); ! 1110: ib_wq_set_drvdata ( &qp->recv, &qib7322->recv_wq[ctx] ); ! 1111: ! 1112: /* Create receive work queue */ ! 1113: if ( ( rc = qib7322_create_recv_wq ( ibdev, qp ) ) != 0 ) ! 1114: goto err_create_recv_wq; ! 1115: ! 1116: /* Create send work queue */ ! 1117: if ( ( rc = qib7322_create_send_wq ( ibdev, qp ) ) != 0 ) ! 1118: goto err_create_send_wq; ! 1119: ! 1120: return 0; ! 1121: ! 1122: qib7322_destroy_send_wq ( ibdev, qp ); ! 1123: err_create_send_wq: ! 1124: qib7322_destroy_recv_wq ( ibdev, qp ); ! 1125: err_create_recv_wq: ! 1126: qib7322_free_ctx ( ibdev, qp ); ! 1127: err_alloc_ctx: ! 1128: return rc; ! 1129: } ! 1130: ! 1131: /** ! 1132: * Modify queue pair ! 1133: * ! 1134: * @v ibdev Infiniband device ! 1135: * @v qp Queue pair ! 1136: * @ret rc Return status code ! 1137: */ ! 1138: static int qib7322_modify_qp ( struct ib_device *ibdev, ! 1139: struct ib_queue_pair *qp ) { ! 1140: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 1141: ! 1142: /* Nothing to do; the hardware doesn't have a notion of queue ! 1143: * keys ! 1144: */ ! 1145: DBGC2 ( qib7322, "QIB7322 %p QPN %ld modified\n", qib7322, qp->qpn ); ! 1146: return 0; ! 1147: } ! 1148: ! 1149: /** ! 1150: * Destroy queue pair ! 1151: * ! 1152: * @v ibdev Infiniband device ! 1153: * @v qp Queue pair ! 1154: */ ! 1155: static void qib7322_destroy_qp ( struct ib_device *ibdev, ! 1156: struct ib_queue_pair *qp ) { ! 1157: ! 1158: qib7322_destroy_send_wq ( ibdev, qp ); ! 1159: qib7322_destroy_recv_wq ( ibdev, qp ); ! 1160: qib7322_free_ctx ( ibdev, qp ); ! 1161: } ! 1162: ! 1163: /*************************************************************************** ! 1164: * ! 1165: * Work request operations ! 1166: * ! 1167: *************************************************************************** ! 1168: */ ! 1169: ! 1170: /** ! 1171: * Post send work queue entry ! 1172: * ! 1173: * @v ibdev Infiniband device ! 1174: * @v qp Queue pair ! 1175: * @v av Address vector ! 1176: * @v iobuf I/O buffer ! 1177: * @ret rc Return status code ! 1178: */ ! 1179: static int qib7322_post_send ( struct ib_device *ibdev, ! 1180: struct ib_queue_pair *qp, ! 1181: struct ib_address_vector *av, ! 1182: struct io_buffer *iobuf ) { ! 1183: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 1184: struct ib_work_queue *wq = &qp->send; ! 1185: struct qib7322_send_work_queue *qib7322_wq = ib_wq_get_drvdata ( wq ); ! 1186: struct QIB_7322_SendPbc sendpbc; ! 1187: unsigned int port = ( ibdev->port - QIB7322_PORT_BASE ); ! 1188: uint8_t header_buf[IB_MAX_HEADER_SIZE]; ! 1189: struct io_buffer headers; ! 1190: int send_buf; ! 1191: unsigned long start_offset; ! 1192: unsigned long offset; ! 1193: size_t len; ! 1194: ssize_t frag_len; ! 1195: uint32_t *data; ! 1196: ! 1197: /* Allocate send buffer and calculate offset */ ! 1198: send_buf = qib7322_alloc_send_buf ( qib7322, qib7322_wq->send_bufs ); ! 1199: if ( send_buf < 0 ) ! 1200: return send_buf; ! 1201: start_offset = offset = ! 1202: qib7322_send_buffer_offset ( qib7322, qib7322_wq->send_bufs, ! 1203: send_buf ); ! 1204: ! 1205: /* Store I/O buffer and send buffer index */ ! 1206: assert ( wq->iobufs[qib7322_wq->prod] == NULL ); ! 1207: wq->iobufs[qib7322_wq->prod] = iobuf; ! 1208: qib7322_wq->used[qib7322_wq->prod] = send_buf; ! 1209: ! 1210: /* Construct headers */ ! 1211: iob_populate ( &headers, header_buf, 0, sizeof ( header_buf ) ); ! 1212: iob_reserve ( &headers, sizeof ( header_buf ) ); ! 1213: ib_push ( ibdev, &headers, qp, iob_len ( iobuf ), av ); ! 1214: ! 1215: /* Calculate packet length */ ! 1216: len = ( ( sizeof ( sendpbc ) + iob_len ( &headers ) + ! 1217: iob_len ( iobuf ) + 3 ) & ~3 ); ! 1218: ! 1219: /* Construct send per-buffer control word */ ! 1220: memset ( &sendpbc, 0, sizeof ( sendpbc ) ); ! 1221: BIT_FILL_3 ( &sendpbc, ! 1222: LengthP1_toibc, ( ( len >> 2 ) - 1 ), ! 1223: Port, port, ! 1224: VL15, ( ( qp->type == IB_QPT_SMI ) ? 1 : 0 ) ); ! 1225: ! 1226: /* Write SendPbc */ ! 1227: DBG_DISABLE ( DBGLVL_IO ); ! 1228: qib7322_writeq ( qib7322, &sendpbc, offset ); ! 1229: offset += sizeof ( sendpbc ); ! 1230: ! 1231: /* Write headers */ ! 1232: for ( data = headers.data, frag_len = iob_len ( &headers ) ; ! 1233: frag_len > 0 ; data++, offset += 4, frag_len -= 4 ) { ! 1234: qib7322_writel ( qib7322, *data, offset ); ! 1235: } ! 1236: ! 1237: /* Write data */ ! 1238: for ( data = iobuf->data, frag_len = iob_len ( iobuf ) ; ! 1239: frag_len > 0 ; data++, offset += 4, frag_len -= 4 ) { ! 1240: qib7322_writel ( qib7322, *data, offset ); ! 1241: } ! 1242: DBG_ENABLE ( DBGLVL_IO ); ! 1243: ! 1244: assert ( ( start_offset + len ) == offset ); ! 1245: DBGC2 ( qib7322, "QIB7322 %p QPN %ld TX %04x(%04x) posted [%lx,%lx)\n", ! 1246: qib7322, qp->qpn, send_buf, qib7322_wq->prod, ! 1247: start_offset, offset ); ! 1248: ! 1249: /* Increment producer counter */ ! 1250: qib7322_wq->prod = ( ( qib7322_wq->prod + 1 ) & ( wq->num_wqes - 1 ) ); ! 1251: ! 1252: return 0; ! 1253: } ! 1254: ! 1255: /** ! 1256: * Complete send work queue entry ! 1257: * ! 1258: * @v ibdev Infiniband device ! 1259: * @v qp Queue pair ! 1260: * @v wqe_idx Work queue entry index ! 1261: */ ! 1262: static void qib7322_complete_send ( struct ib_device *ibdev, ! 1263: struct ib_queue_pair *qp, ! 1264: unsigned int wqe_idx ) { ! 1265: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 1266: struct ib_work_queue *wq = &qp->send; ! 1267: struct qib7322_send_work_queue *qib7322_wq = ib_wq_get_drvdata ( wq ); ! 1268: struct io_buffer *iobuf; ! 1269: unsigned int send_buf; ! 1270: ! 1271: /* Parse completion */ ! 1272: send_buf = qib7322_wq->used[wqe_idx]; ! 1273: DBGC2 ( qib7322, "QIB7322 %p QPN %ld TX %04x(%04x) complete\n", ! 1274: qib7322, qp->qpn, send_buf, wqe_idx ); ! 1275: ! 1276: /* Complete work queue entry */ ! 1277: iobuf = wq->iobufs[wqe_idx]; ! 1278: assert ( iobuf != NULL ); ! 1279: ib_complete_send ( ibdev, qp, iobuf, 0 ); ! 1280: wq->iobufs[wqe_idx] = NULL; ! 1281: ! 1282: /* Free send buffer */ ! 1283: qib7322_free_send_buf ( qib7322, qib7322_wq->send_bufs, send_buf ); ! 1284: } ! 1285: ! 1286: /** ! 1287: * Poll send work queue ! 1288: * ! 1289: * @v ibdev Infiniband device ! 1290: * @v qp Queue pair ! 1291: */ ! 1292: static void qib7322_poll_send_wq ( struct ib_device *ibdev, ! 1293: struct ib_queue_pair *qp ) { ! 1294: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 1295: struct ib_work_queue *wq = &qp->send; ! 1296: struct qib7322_send_work_queue *qib7322_wq = ib_wq_get_drvdata ( wq ); ! 1297: unsigned int send_buf; ! 1298: ! 1299: /* Look for completions */ ! 1300: while ( wq->fill ) { ! 1301: ! 1302: /* Check to see if send buffer has completed */ ! 1303: send_buf = qib7322_wq->used[qib7322_wq->cons]; ! 1304: if ( qib7322_send_buf_in_use ( qib7322, send_buf ) ) ! 1305: break; ! 1306: ! 1307: /* Complete this buffer */ ! 1308: qib7322_complete_send ( ibdev, qp, qib7322_wq->cons ); ! 1309: ! 1310: /* Increment consumer counter */ ! 1311: qib7322_wq->cons = ( ( qib7322_wq->cons + 1 ) & ! 1312: ( wq->num_wqes - 1 ) ); ! 1313: } ! 1314: } ! 1315: ! 1316: /** ! 1317: * Post receive work queue entry ! 1318: * ! 1319: * @v ibdev Infiniband device ! 1320: * @v qp Queue pair ! 1321: * @v iobuf I/O buffer ! 1322: * @ret rc Return status code ! 1323: */ ! 1324: static int qib7322_post_recv ( struct ib_device *ibdev, ! 1325: struct ib_queue_pair *qp, ! 1326: struct io_buffer *iobuf ) { ! 1327: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 1328: struct ib_work_queue *wq = &qp->recv; ! 1329: struct qib7322_recv_work_queue *qib7322_wq = ib_wq_get_drvdata ( wq ); ! 1330: struct QIB_7322_RcvEgr rcvegr; ! 1331: struct QIB_7322_scalar rcvegrindexhead; ! 1332: unsigned int ctx = qib7322_ctx ( ibdev, qp ); ! 1333: physaddr_t addr; ! 1334: size_t len; ! 1335: unsigned int wqe_idx; ! 1336: unsigned int bufsize; ! 1337: ! 1338: /* Sanity checks */ ! 1339: addr = virt_to_bus ( iobuf->data ); ! 1340: len = iob_tailroom ( iobuf ); ! 1341: if ( addr & ( QIB7322_EAGER_BUFFER_ALIGN - 1 ) ) { ! 1342: DBGC ( qib7322, "QIB7322 %p QPN %ld misaligned RX buffer " ! 1343: "(%08lx)\n", qib7322, qp->qpn, addr ); ! 1344: return -EINVAL; ! 1345: } ! 1346: if ( len != QIB7322_RECV_PAYLOAD_SIZE ) { ! 1347: DBGC ( qib7322, "QIB7322 %p QPN %ld wrong RX buffer size " ! 1348: "(%zd)\n", qib7322, qp->qpn, len ); ! 1349: return -EINVAL; ! 1350: } ! 1351: ! 1352: /* Calculate eager producer index and WQE index */ ! 1353: wqe_idx = ( qib7322_wq->eager_prod & ( wq->num_wqes - 1 ) ); ! 1354: assert ( wq->iobufs[wqe_idx] == NULL ); ! 1355: ! 1356: /* Store I/O buffer */ ! 1357: wq->iobufs[wqe_idx] = iobuf; ! 1358: ! 1359: /* Calculate buffer size */ ! 1360: switch ( QIB7322_RECV_PAYLOAD_SIZE ) { ! 1361: case 2048: bufsize = QIB7322_EAGER_BUFFER_2K; break; ! 1362: case 4096: bufsize = QIB7322_EAGER_BUFFER_4K; break; ! 1363: case 8192: bufsize = QIB7322_EAGER_BUFFER_8K; break; ! 1364: case 16384: bufsize = QIB7322_EAGER_BUFFER_16K; break; ! 1365: case 32768: bufsize = QIB7322_EAGER_BUFFER_32K; break; ! 1366: case 65536: bufsize = QIB7322_EAGER_BUFFER_64K; break; ! 1367: default: linker_assert ( 0, invalid_rx_payload_size ); ! 1368: bufsize = QIB7322_EAGER_BUFFER_NONE; ! 1369: } ! 1370: ! 1371: /* Post eager buffer */ ! 1372: memset ( &rcvegr, 0, sizeof ( rcvegr ) ); ! 1373: BIT_FILL_2 ( &rcvegr, ! 1374: Addr, ( addr >> 11 ), ! 1375: BufSize, bufsize ); ! 1376: qib7322_writeq_array8b ( qib7322, &rcvegr, qib7322_wq->eager_array, ! 1377: qib7322_wq->eager_prod ); ! 1378: DBGC2 ( qib7322, "QIB7322 %p QPN %ld RX egr %04x(%04x) posted " ! 1379: "[%lx,%lx)\n", qib7322, qp->qpn, qib7322_wq->eager_prod, ! 1380: wqe_idx, addr, ( addr + len ) ); ! 1381: ! 1382: /* Increment producer index */ ! 1383: qib7322_wq->eager_prod = ( ( qib7322_wq->eager_prod + 1 ) & ! 1384: ( qib7322_wq->eager_entries - 1 ) ); ! 1385: ! 1386: /* Update head index */ ! 1387: memset ( &rcvegrindexhead, 0, sizeof ( rcvegrindexhead ) ); ! 1388: BIT_FILL_1 ( &rcvegrindexhead, ! 1389: Value, ( ( qib7322_wq->eager_prod + 1 ) & ! 1390: ( qib7322_wq->eager_entries - 1 ) ) ); ! 1391: qib7322_writeq_array64k ( qib7322, &rcvegrindexhead, ! 1392: QIB_7322_RcvEgrIndexHead0_offset, ctx ); ! 1393: ! 1394: return 0; ! 1395: } ! 1396: ! 1397: /** ! 1398: * Complete receive work queue entry ! 1399: * ! 1400: * @v ibdev Infiniband device ! 1401: * @v qp Queue pair ! 1402: * @v header_offs Header offset ! 1403: */ ! 1404: static void qib7322_complete_recv ( struct ib_device *ibdev, ! 1405: struct ib_queue_pair *qp, ! 1406: unsigned int header_offs ) { ! 1407: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 1408: struct ib_work_queue *wq = &qp->recv; ! 1409: struct qib7322_recv_work_queue *qib7322_wq = ib_wq_get_drvdata ( wq ); ! 1410: struct QIB_7322_RcvHdrFlags *rcvhdrflags; ! 1411: struct QIB_7322_RcvEgr rcvegr; ! 1412: struct io_buffer headers; ! 1413: struct io_buffer *iobuf; ! 1414: struct ib_queue_pair *intended_qp; ! 1415: struct ib_address_vector av; ! 1416: unsigned int rcvtype; ! 1417: unsigned int pktlen; ! 1418: unsigned int egrindex; ! 1419: unsigned int useegrbfr; ! 1420: unsigned int iberr, mkerr, tiderr, khdrerr, mtuerr; ! 1421: unsigned int lenerr, parityerr, vcrcerr, icrcerr; ! 1422: unsigned int err; ! 1423: unsigned int hdrqoffset; ! 1424: unsigned int header_len; ! 1425: unsigned int padded_payload_len; ! 1426: unsigned int wqe_idx; ! 1427: size_t payload_len; ! 1428: int qp0; ! 1429: int rc; ! 1430: ! 1431: /* RcvHdrFlags are at the end of the header entry */ ! 1432: rcvhdrflags = ( qib7322_wq->header + header_offs + ! 1433: QIB7322_RECV_HEADER_SIZE - sizeof ( *rcvhdrflags ) ); ! 1434: rcvtype = BIT_GET ( rcvhdrflags, RcvType ); ! 1435: pktlen = ( BIT_GET ( rcvhdrflags, PktLen ) << 2 ); ! 1436: egrindex = BIT_GET ( rcvhdrflags, EgrIndex ); ! 1437: useegrbfr = BIT_GET ( rcvhdrflags, UseEgrBfr ); ! 1438: hdrqoffset = ( BIT_GET ( rcvhdrflags, HdrqOffset ) << 2 ); ! 1439: iberr = BIT_GET ( rcvhdrflags, IBErr ); ! 1440: mkerr = BIT_GET ( rcvhdrflags, MKErr ); ! 1441: tiderr = BIT_GET ( rcvhdrflags, TIDErr ); ! 1442: khdrerr = BIT_GET ( rcvhdrflags, KHdrErr ); ! 1443: mtuerr = BIT_GET ( rcvhdrflags, MTUErr ); ! 1444: lenerr = BIT_GET ( rcvhdrflags, LenErr ); ! 1445: parityerr = BIT_GET ( rcvhdrflags, ParityErr ); ! 1446: vcrcerr = BIT_GET ( rcvhdrflags, VCRCErr ); ! 1447: icrcerr = BIT_GET ( rcvhdrflags, ICRCErr ); ! 1448: header_len = ( QIB7322_RECV_HEADER_SIZE - hdrqoffset - ! 1449: sizeof ( *rcvhdrflags ) ); ! 1450: padded_payload_len = ( pktlen - header_len - 4 /* ICRC */ ); ! 1451: err = ( iberr | mkerr | tiderr | khdrerr | mtuerr | ! 1452: lenerr | parityerr | vcrcerr | icrcerr ); ! 1453: /* IB header is placed immediately before RcvHdrFlags */ ! 1454: iob_populate ( &headers, ( ( ( void * ) rcvhdrflags ) - header_len ), ! 1455: header_len, header_len ); ! 1456: ! 1457: /* Dump diagnostic information */ ! 1458: DBGC2 ( qib7322, "QIB7322 %p QPN %ld RX egr %04x%s hdr %d type %d len " ! 1459: "%d(%d+%d+4)%s%s%s%s%s%s%s%s%s%s%s\n", qib7322, qp->qpn, ! 1460: egrindex, ( useegrbfr ? "" : "(unused)" ), ! 1461: ( header_offs / QIB7322_RECV_HEADER_SIZE ), ! 1462: rcvtype, pktlen, header_len, padded_payload_len, ! 1463: ( err ? " [Err" : "" ), ( iberr ? " IB" : "" ), ! 1464: ( mkerr ? " MK" : "" ), ( tiderr ? " TID" : "" ), ! 1465: ( khdrerr ? " KHdr" : "" ), ( mtuerr ? " MTU" : "" ), ! 1466: ( lenerr ? " Len" : "" ), ( parityerr ? " Parity" : ""), ! 1467: ( vcrcerr ? " VCRC" : "" ), ( icrcerr ? " ICRC" : "" ), ! 1468: ( err ? "]" : "" ) ); ! 1469: DBGCP_HDA ( qib7322, hdrqoffset, headers.data, ! 1470: ( header_len + sizeof ( *rcvhdrflags ) ) ); ! 1471: ! 1472: /* Parse header to generate address vector */ ! 1473: qp0 = ( qp->qpn == 0 ); ! 1474: intended_qp = NULL; ! 1475: if ( ( rc = ib_pull ( ibdev, &headers, ( qp0 ? &intended_qp : NULL ), ! 1476: &payload_len, &av ) ) != 0 ) { ! 1477: DBGC ( qib7322, "QIB7322 %p could not parse headers: %s\n", ! 1478: qib7322, strerror ( rc ) ); ! 1479: err = 1; ! 1480: } ! 1481: if ( ! intended_qp ) ! 1482: intended_qp = qp; ! 1483: ! 1484: /* Complete this buffer and any skipped buffers. Note that ! 1485: * when the hardware runs out of buffers, it will repeatedly ! 1486: * report the same buffer (the tail) as a TID error, and that ! 1487: * it also has a habit of sometimes skipping over several ! 1488: * buffers at once. ! 1489: */ ! 1490: while ( 1 ) { ! 1491: ! 1492: /* If we have caught up to the producer counter, stop. ! 1493: * This will happen when the hardware first runs out ! 1494: * of buffers and starts reporting TID errors against ! 1495: * the eager buffer it wants to use next. ! 1496: */ ! 1497: if ( qib7322_wq->eager_cons == qib7322_wq->eager_prod ) ! 1498: break; ! 1499: ! 1500: /* If we have caught up to where we should be after ! 1501: * completing this egrindex, stop. We phrase the test ! 1502: * this way to avoid completing the entire ring when ! 1503: * we receive the same egrindex twice in a row. ! 1504: */ ! 1505: if ( ( qib7322_wq->eager_cons == ! 1506: ( ( egrindex + 1 ) & ( qib7322_wq->eager_entries - 1 )))) ! 1507: break; ! 1508: ! 1509: /* Identify work queue entry and corresponding I/O ! 1510: * buffer. ! 1511: */ ! 1512: wqe_idx = ( qib7322_wq->eager_cons & ( wq->num_wqes - 1 ) ); ! 1513: iobuf = wq->iobufs[wqe_idx]; ! 1514: assert ( iobuf != NULL ); ! 1515: wq->iobufs[wqe_idx] = NULL; ! 1516: ! 1517: /* Complete the eager buffer */ ! 1518: if ( qib7322_wq->eager_cons == egrindex ) { ! 1519: /* Completing the eager buffer described in ! 1520: * this header entry. ! 1521: */ ! 1522: iob_put ( iobuf, payload_len ); ! 1523: rc = ( err ? -EIO : ( useegrbfr ? 0 : -ECANCELED ) ); ! 1524: /* Redirect to target QP if necessary */ ! 1525: if ( qp != intended_qp ) { ! 1526: DBGC2 ( qib7322, "QIB7322 %p redirecting QPN " ! 1527: "%ld => %ld\n", ! 1528: qib7322, qp->qpn, intended_qp->qpn ); ! 1529: /* Compensate for incorrect fill levels */ ! 1530: qp->recv.fill--; ! 1531: intended_qp->recv.fill++; ! 1532: } ! 1533: ib_complete_recv ( ibdev, intended_qp, &av, iobuf, rc); ! 1534: } else { ! 1535: /* Completing on a skipped-over eager buffer */ ! 1536: ib_complete_recv ( ibdev, qp, &av, iobuf, -ECANCELED ); ! 1537: } ! 1538: ! 1539: /* Clear eager buffer */ ! 1540: memset ( &rcvegr, 0, sizeof ( rcvegr ) ); ! 1541: qib7322_writeq_array8b ( qib7322, &rcvegr, ! 1542: qib7322_wq->eager_array, ! 1543: qib7322_wq->eager_cons ); ! 1544: ! 1545: /* Increment consumer index */ ! 1546: qib7322_wq->eager_cons = ( ( qib7322_wq->eager_cons + 1 ) & ! 1547: ( qib7322_wq->eager_entries - 1 ) ); ! 1548: } ! 1549: } ! 1550: ! 1551: /** ! 1552: * Poll receive work queue ! 1553: * ! 1554: * @v ibdev Infiniband device ! 1555: * @v qp Queue pair ! 1556: */ ! 1557: static void qib7322_poll_recv_wq ( struct ib_device *ibdev, ! 1558: struct ib_queue_pair *qp ) { ! 1559: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 1560: struct ib_work_queue *wq = &qp->recv; ! 1561: struct qib7322_recv_work_queue *qib7322_wq = ib_wq_get_drvdata ( wq ); ! 1562: struct QIB_7322_RcvHdrHead0 rcvhdrhead; ! 1563: unsigned int ctx = qib7322_ctx ( ibdev, qp ); ! 1564: unsigned int header_prod; ! 1565: ! 1566: /* Check for received packets */ ! 1567: header_prod = ( BIT_GET ( &qib7322_wq->header_prod, Value ) << 2 ); ! 1568: if ( header_prod == qib7322_wq->header_cons ) ! 1569: return; ! 1570: ! 1571: /* Process all received packets */ ! 1572: while ( qib7322_wq->header_cons != header_prod ) { ! 1573: ! 1574: /* Complete the receive */ ! 1575: qib7322_complete_recv ( ibdev, qp, qib7322_wq->header_cons ); ! 1576: ! 1577: /* Increment the consumer offset */ ! 1578: qib7322_wq->header_cons += QIB7322_RECV_HEADER_SIZE; ! 1579: qib7322_wq->header_cons %= QIB7322_RECV_HEADERS_SIZE; ! 1580: ! 1581: /* QIB7322 has only one send buffer per port for VL15, ! 1582: * which almost always leads to send buffer exhaustion ! 1583: * and dropped MADs. Mitigate this by refusing to ! 1584: * process more than one VL15 MAD per poll, which will ! 1585: * enforce interleaved TX/RX polls. ! 1586: */ ! 1587: if ( qp->type == IB_QPT_SMI ) ! 1588: break; ! 1589: } ! 1590: ! 1591: /* Update consumer offset */ ! 1592: memset ( &rcvhdrhead, 0, sizeof ( rcvhdrhead ) ); ! 1593: BIT_FILL_2 ( &rcvhdrhead, ! 1594: RcvHeadPointer, ( qib7322_wq->header_cons >> 2 ), ! 1595: counter, 1 ); ! 1596: qib7322_writeq_array64k ( qib7322, &rcvhdrhead, ! 1597: QIB_7322_RcvHdrHead0_offset, ctx ); ! 1598: } ! 1599: ! 1600: /** ! 1601: * Poll completion queue ! 1602: * ! 1603: * @v ibdev Infiniband device ! 1604: * @v cq Completion queue ! 1605: */ ! 1606: static void qib7322_poll_cq ( struct ib_device *ibdev, ! 1607: struct ib_completion_queue *cq ) { ! 1608: struct ib_work_queue *wq; ! 1609: ! 1610: /* Poll associated send and receive queues */ ! 1611: list_for_each_entry ( wq, &cq->work_queues, list ) { ! 1612: if ( wq->is_send ) { ! 1613: qib7322_poll_send_wq ( ibdev, wq->qp ); ! 1614: } else { ! 1615: qib7322_poll_recv_wq ( ibdev, wq->qp ); ! 1616: } ! 1617: } ! 1618: } ! 1619: ! 1620: /*************************************************************************** ! 1621: * ! 1622: * Event queues ! 1623: * ! 1624: *************************************************************************** ! 1625: */ ! 1626: ! 1627: /** ! 1628: * Poll event queue ! 1629: * ! 1630: * @v ibdev Infiniband device ! 1631: */ ! 1632: static void qib7322_poll_eq ( struct ib_device *ibdev ) { ! 1633: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 1634: struct QIB_7322_ErrStatus_0 errstatus; ! 1635: unsigned int port = ( ibdev->port - QIB7322_PORT_BASE ); ! 1636: ! 1637: /* Check for and clear status bits */ ! 1638: DBG_DISABLE ( DBGLVL_IO ); ! 1639: qib7322_readq_port ( qib7322, &errstatus, ! 1640: QIB_7322_ErrStatus_0_offset, port ); ! 1641: if ( errstatus.u.qwords[0] ) { ! 1642: DBGC ( qib7322, "QIB7322 %p port %d status %08x%08x\n", qib7322, ! 1643: port, errstatus.u.dwords[1], errstatus.u.dwords[0] ); ! 1644: qib7322_writeq_port ( qib7322, &errstatus, ! 1645: QIB_7322_ErrClear_0_offset, port ); ! 1646: } ! 1647: DBG_ENABLE ( DBGLVL_IO ); ! 1648: ! 1649: /* Check for link status changes */ ! 1650: if ( BIT_GET ( &errstatus, IBStatusChanged ) ) ! 1651: qib7322_link_state_changed ( ibdev ); ! 1652: } ! 1653: ! 1654: /*************************************************************************** ! 1655: * ! 1656: * Infiniband link-layer operations ! 1657: * ! 1658: *************************************************************************** ! 1659: */ ! 1660: ! 1661: /** ! 1662: * Determine supported link speeds ! 1663: * ! 1664: * @v qib7322 QIB7322 device ! 1665: * @ret supported Supported link speeds ! 1666: */ ! 1667: static unsigned int qib7322_link_speed_supported ( struct qib7322 *qib7322, ! 1668: unsigned int port ) { ! 1669: struct QIB_7322_feature_mask features; ! 1670: struct QIB_7322_Revision revision; ! 1671: unsigned int supported; ! 1672: unsigned int boardid; ! 1673: ! 1674: /* Read the active feature mask */ ! 1675: qib7322_readq ( qib7322, &features, ! 1676: QIB_7322_active_feature_mask_offset ); ! 1677: switch ( port ) { ! 1678: case 0 : ! 1679: supported = BIT_GET ( &features, Port0_Link_Speed_Supported ); ! 1680: break; ! 1681: case 1 : ! 1682: supported = BIT_GET ( &features, Port1_Link_Speed_Supported ); ! 1683: break; ! 1684: default: ! 1685: DBGC ( qib7322, "QIB7322 %p port %d is invalid\n", ! 1686: qib7322, port ); ! 1687: supported = 0; ! 1688: break; ! 1689: } ! 1690: ! 1691: /* Apply hacks for specific board IDs */ ! 1692: qib7322_readq ( qib7322, &revision, QIB_7322_Revision_offset ); ! 1693: boardid = BIT_GET ( &revision, BoardID ); ! 1694: switch ( boardid ) { ! 1695: case QIB7322_BOARD_QMH7342 : ! 1696: DBGC2 ( qib7322, "QIB7322 %p is a QMH7342; forcing QDR-only\n", ! 1697: qib7322 ); ! 1698: supported = IB_LINK_SPEED_QDR; ! 1699: break; ! 1700: default: ! 1701: /* Do nothing */ ! 1702: break; ! 1703: } ! 1704: ! 1705: DBGC2 ( qib7322, "QIB7322 %p port %d %s%s%s%s\n", qib7322, port, ! 1706: ( supported ? "supports" : "disabled" ), ! 1707: ( ( supported & IB_LINK_SPEED_SDR ) ? " SDR" : "" ), ! 1708: ( ( supported & IB_LINK_SPEED_DDR ) ? " DDR" : "" ), ! 1709: ( ( supported & IB_LINK_SPEED_QDR ) ? " QDR" : "" ) ); ! 1710: return supported; ! 1711: } ! 1712: ! 1713: /** ! 1714: * Initialise Infiniband link ! 1715: * ! 1716: * @v ibdev Infiniband device ! 1717: * @ret rc Return status code ! 1718: */ ! 1719: static int qib7322_open ( struct ib_device *ibdev ) { ! 1720: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 1721: struct QIB_7322_IBCCtrlA_0 ibcctrla; ! 1722: unsigned int port = ( ibdev->port - QIB7322_PORT_BASE ); ! 1723: ! 1724: /* Enable link */ ! 1725: qib7322_readq_port ( qib7322, &ibcctrla, ! 1726: QIB_7322_IBCCtrlA_0_offset, port ); ! 1727: BIT_SET ( &ibcctrla, IBLinkEn, 1 ); ! 1728: qib7322_writeq_port ( qib7322, &ibcctrla, ! 1729: QIB_7322_IBCCtrlA_0_offset, port ); ! 1730: ! 1731: return 0; ! 1732: } ! 1733: ! 1734: /** ! 1735: * Close Infiniband link ! 1736: * ! 1737: * @v ibdev Infiniband device ! 1738: */ ! 1739: static void qib7322_close ( struct ib_device *ibdev ) { ! 1740: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 1741: struct QIB_7322_IBCCtrlA_0 ibcctrla; ! 1742: unsigned int port = ( ibdev->port - QIB7322_PORT_BASE ); ! 1743: ! 1744: /* Disable link */ ! 1745: qib7322_readq_port ( qib7322, &ibcctrla, ! 1746: QIB_7322_IBCCtrlA_0_offset, port ); ! 1747: BIT_SET ( &ibcctrla, IBLinkEn, 0 ); ! 1748: qib7322_writeq_port ( qib7322, &ibcctrla, ! 1749: QIB_7322_IBCCtrlA_0_offset, port ); ! 1750: } ! 1751: ! 1752: /*************************************************************************** ! 1753: * ! 1754: * Multicast group operations ! 1755: * ! 1756: *************************************************************************** ! 1757: */ ! 1758: ! 1759: /** ! 1760: * Attach to multicast group ! 1761: * ! 1762: * @v ibdev Infiniband device ! 1763: * @v qp Queue pair ! 1764: * @v gid Multicast GID ! 1765: * @ret rc Return status code ! 1766: */ ! 1767: static int qib7322_mcast_attach ( struct ib_device *ibdev, ! 1768: struct ib_queue_pair *qp, ! 1769: union ib_gid *gid ) { ! 1770: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 1771: ! 1772: ( void ) qib7322; ! 1773: ( void ) qp; ! 1774: ( void ) gid; ! 1775: return 0; ! 1776: } ! 1777: ! 1778: /** ! 1779: * Detach from multicast group ! 1780: * ! 1781: * @v ibdev Infiniband device ! 1782: * @v qp Queue pair ! 1783: * @v gid Multicast GID ! 1784: */ ! 1785: static void qib7322_mcast_detach ( struct ib_device *ibdev, ! 1786: struct ib_queue_pair *qp, ! 1787: union ib_gid *gid ) { ! 1788: struct qib7322 *qib7322 = ib_get_drvdata ( ibdev ); ! 1789: ! 1790: ( void ) qib7322; ! 1791: ( void ) qp; ! 1792: ( void ) gid; ! 1793: } ! 1794: ! 1795: /** QIB7322 Infiniband operations */ ! 1796: static struct ib_device_operations qib7322_ib_operations = { ! 1797: .create_cq = qib7322_create_cq, ! 1798: .destroy_cq = qib7322_destroy_cq, ! 1799: .create_qp = qib7322_create_qp, ! 1800: .modify_qp = qib7322_modify_qp, ! 1801: .destroy_qp = qib7322_destroy_qp, ! 1802: .post_send = qib7322_post_send, ! 1803: .post_recv = qib7322_post_recv, ! 1804: .poll_cq = qib7322_poll_cq, ! 1805: .poll_eq = qib7322_poll_eq, ! 1806: .open = qib7322_open, ! 1807: .close = qib7322_close, ! 1808: .mcast_attach = qib7322_mcast_attach, ! 1809: .mcast_detach = qib7322_mcast_detach, ! 1810: .set_port_info = qib7322_set_port_info, ! 1811: .set_pkey_table = qib7322_set_pkey_table, ! 1812: }; ! 1813: ! 1814: /*************************************************************************** ! 1815: * ! 1816: * I2C bus operations ! 1817: * ! 1818: *************************************************************************** ! 1819: */ ! 1820: ! 1821: /** QIB7322 I2C bit to GPIO mappings */ ! 1822: static unsigned int qib7322_i2c_bits[] = { ! 1823: [I2C_BIT_SCL] = ( 1 << QIB7322_GPIO_SCL ), ! 1824: [I2C_BIT_SDA] = ( 1 << QIB7322_GPIO_SDA ), ! 1825: }; ! 1826: ! 1827: /** ! 1828: * Read QIB7322 I2C line status ! 1829: * ! 1830: * @v basher Bit-bashing interface ! 1831: * @v bit_id Bit number ! 1832: * @ret zero Input is a logic 0 ! 1833: * @ret non-zero Input is a logic 1 ! 1834: */ ! 1835: static int qib7322_i2c_read_bit ( struct bit_basher *basher, ! 1836: unsigned int bit_id ) { ! 1837: struct qib7322 *qib7322 = ! 1838: container_of ( basher, struct qib7322, i2c.basher ); ! 1839: struct QIB_7322_EXTStatus extstatus; ! 1840: unsigned int status; ! 1841: ! 1842: DBG_DISABLE ( DBGLVL_IO ); ! 1843: ! 1844: qib7322_readq ( qib7322, &extstatus, QIB_7322_EXTStatus_offset ); ! 1845: status = ( BIT_GET ( &extstatus, GPIOIn ) & qib7322_i2c_bits[bit_id] ); ! 1846: ! 1847: DBG_ENABLE ( DBGLVL_IO ); ! 1848: ! 1849: return status; ! 1850: } ! 1851: ! 1852: /** ! 1853: * Write QIB7322 I2C line status ! 1854: * ! 1855: * @v basher Bit-bashing interface ! 1856: * @v bit_id Bit number ! 1857: * @v data Value to write ! 1858: */ ! 1859: static void qib7322_i2c_write_bit ( struct bit_basher *basher, ! 1860: unsigned int bit_id, unsigned long data ) { ! 1861: struct qib7322 *qib7322 = ! 1862: container_of ( basher, struct qib7322, i2c.basher ); ! 1863: struct QIB_7322_EXTCtrl extctrl; ! 1864: struct QIB_7322_GPIO gpioout; ! 1865: unsigned int bit = qib7322_i2c_bits[bit_id]; ! 1866: unsigned int outputs = 0; ! 1867: unsigned int output_enables = 0; ! 1868: ! 1869: DBG_DISABLE ( DBGLVL_IO ); ! 1870: ! 1871: /* Read current GPIO mask and outputs */ ! 1872: qib7322_readq ( qib7322, &extctrl, QIB_7322_EXTCtrl_offset ); ! 1873: qib7322_readq ( qib7322, &gpioout, QIB_7322_GPIOOut_offset ); ! 1874: ! 1875: /* Update outputs and output enables. I2C lines are tied ! 1876: * high, so we always set the output to 0 and use the output ! 1877: * enable to control the line. ! 1878: */ ! 1879: output_enables = BIT_GET ( &extctrl, GPIOOe ); ! 1880: output_enables = ( ( output_enables & ~bit ) | ( ~data & bit ) ); ! 1881: outputs = BIT_GET ( &gpioout, GPIO ); ! 1882: outputs = ( outputs & ~bit ); ! 1883: BIT_SET ( &extctrl, GPIOOe, output_enables ); ! 1884: BIT_SET ( &gpioout, GPIO, outputs ); ! 1885: ! 1886: /* Write the output enable first; that way we avoid logic ! 1887: * hazards. ! 1888: */ ! 1889: qib7322_writeq ( qib7322, &extctrl, QIB_7322_EXTCtrl_offset ); ! 1890: qib7322_writeq ( qib7322, &gpioout, QIB_7322_GPIOOut_offset ); ! 1891: mb(); ! 1892: ! 1893: DBG_ENABLE ( DBGLVL_IO ); ! 1894: } ! 1895: ! 1896: /** QIB7322 I2C bit-bashing interface operations */ ! 1897: static struct bit_basher_operations qib7322_i2c_basher_ops = { ! 1898: .read = qib7322_i2c_read_bit, ! 1899: .write = qib7322_i2c_write_bit, ! 1900: }; ! 1901: ! 1902: /** ! 1903: * Initialise QIB7322 I2C subsystem ! 1904: * ! 1905: * @v qib7322 QIB7322 device ! 1906: * @ret rc Return status code ! 1907: */ ! 1908: static int qib7322_init_i2c ( struct qib7322 *qib7322 ) { ! 1909: static int try_eeprom_address[] = { 0x51, 0x50 }; ! 1910: unsigned int i; ! 1911: int rc; ! 1912: ! 1913: /* Initialise bus */ ! 1914: if ( ( rc = init_i2c_bit_basher ( &qib7322->i2c, ! 1915: &qib7322_i2c_basher_ops ) ) != 0 ) { ! 1916: DBGC ( qib7322, "QIB7322 %p could not initialise I2C bus: %s\n", ! 1917: qib7322, strerror ( rc ) ); ! 1918: return rc; ! 1919: } ! 1920: ! 1921: /* Probe for devices */ ! 1922: for ( i = 0 ; i < ( sizeof ( try_eeprom_address ) / ! 1923: sizeof ( try_eeprom_address[0] ) ) ; i++ ) { ! 1924: init_i2c_eeprom ( &qib7322->eeprom, try_eeprom_address[i] ); ! 1925: if ( ( rc = i2c_check_presence ( &qib7322->i2c.i2c, ! 1926: &qib7322->eeprom ) ) == 0 ) { ! 1927: DBGC2 ( qib7322, "QIB7322 %p found EEPROM at %02x\n", ! 1928: qib7322, try_eeprom_address[i] ); ! 1929: return 0; ! 1930: } ! 1931: } ! 1932: ! 1933: DBGC ( qib7322, "QIB7322 %p could not find EEPROM\n", qib7322 ); ! 1934: return -ENODEV; ! 1935: } ! 1936: ! 1937: /** ! 1938: * Read EEPROM parameters ! 1939: * ! 1940: * @v qib7322 QIB7322 device ! 1941: * @ret rc Return status code ! 1942: */ ! 1943: static int qib7322_read_eeprom ( struct qib7322 *qib7322 ) { ! 1944: struct i2c_interface *i2c = &qib7322->i2c.i2c; ! 1945: union ib_guid *guid = &qib7322->guid; ! 1946: int rc; ! 1947: ! 1948: /* Read GUID */ ! 1949: if ( ( rc = i2c->read ( i2c, &qib7322->eeprom, ! 1950: QIB7322_EEPROM_GUID_OFFSET, guid->bytes, ! 1951: sizeof ( *guid ) ) ) != 0 ) { ! 1952: DBGC ( qib7322, "QIB7322 %p could not read GUID: %s\n", ! 1953: qib7322, strerror ( rc ) ); ! 1954: return rc; ! 1955: } ! 1956: DBGC2 ( qib7322, "QIB7322 %p has GUID " IB_GUID_FMT "\n", ! 1957: qib7322, IB_GUID_ARGS ( guid ) ); ! 1958: ! 1959: /* Read serial number (debug only) */ ! 1960: if ( DBG_LOG ) { ! 1961: uint8_t serial[QIB7322_EEPROM_SERIAL_SIZE + 1]; ! 1962: ! 1963: serial[ sizeof ( serial ) - 1 ] = '\0'; ! 1964: if ( ( rc = i2c->read ( i2c, &qib7322->eeprom, ! 1965: QIB7322_EEPROM_SERIAL_OFFSET, serial, ! 1966: ( sizeof ( serial ) - 1 ) ) ) != 0 ) { ! 1967: DBGC ( qib7322, "QIB7322 %p could not read serial: " ! 1968: "%s\n", qib7322, strerror ( rc ) ); ! 1969: return rc; ! 1970: } ! 1971: DBGC2 ( qib7322, "QIB7322 %p has serial number \"%s\"\n", ! 1972: qib7322, serial ); ! 1973: } ! 1974: ! 1975: return 0; ! 1976: } ! 1977: ! 1978: /*************************************************************************** ! 1979: * ! 1980: * Advanced High-performance Bus (AHB) access ! 1981: * ! 1982: *************************************************************************** ! 1983: */ ! 1984: ! 1985: /** ! 1986: * Wait for AHB transaction to complete ! 1987: * ! 1988: * @v qib7322 QIB7322 device ! 1989: * @ret rc Return status code ! 1990: */ ! 1991: static int qib7322_ahb_wait ( struct qib7322 *qib7322 ) { ! 1992: struct QIB_7322_ahb_transaction_reg transaction; ! 1993: unsigned int i; ! 1994: ! 1995: /* Wait for Ready bit to be asserted */ ! 1996: for ( i = 0 ; i < QIB7322_AHB_MAX_WAIT_US ; i++ ) { ! 1997: qib7322_readq ( qib7322, &transaction, ! 1998: QIB_7322_ahb_transaction_reg_offset ); ! 1999: if ( BIT_GET ( &transaction, ahb_rdy ) ) ! 2000: return 0; ! 2001: udelay ( 1 ); ! 2002: } ! 2003: ! 2004: DBGC ( qib7322, "QIB7322 %p timed out waiting for AHB transaction\n", ! 2005: qib7322 ); ! 2006: return -ETIMEDOUT; ! 2007: } ! 2008: ! 2009: /** ! 2010: * Request ownership of the AHB ! 2011: * ! 2012: * @v qib7322 QIB7322 device ! 2013: * @v location AHB location ! 2014: * @ret rc Return status code ! 2015: */ ! 2016: static int qib7322_ahb_request ( struct qib7322 *qib7322, ! 2017: unsigned int location ) { ! 2018: struct QIB_7322_ahb_access_ctrl access; ! 2019: int rc; ! 2020: ! 2021: /* Request ownership */ ! 2022: memset ( &access, 0, sizeof ( access ) ); ! 2023: BIT_FILL_2 ( &access, ! 2024: sw_ahb_sel, 1, ! 2025: sw_sel_ahb_trgt, QIB7322_AHB_LOC_TARGET ( location ) ); ! 2026: qib7322_writeq ( qib7322, &access, QIB_7322_ahb_access_ctrl_offset ); ! 2027: ! 2028: /* Wait for ownership to be granted */ ! 2029: if ( ( rc = qib7322_ahb_wait ( qib7322 ) ) != 0 ) { ! 2030: DBGC ( qib7322, "QIB7322 %p could not obtain AHB ownership: " ! 2031: "%s\n", qib7322, strerror ( rc ) ); ! 2032: return rc; ! 2033: } ! 2034: ! 2035: return 0; ! 2036: } ! 2037: ! 2038: /** ! 2039: * Release ownership of the AHB ! 2040: * ! 2041: * @v qib7322 QIB7322 device ! 2042: */ ! 2043: static void qib7322_ahb_release ( struct qib7322 *qib7322 ) { ! 2044: struct QIB_7322_ahb_access_ctrl access; ! 2045: ! 2046: memset ( &access, 0, sizeof ( access ) ); ! 2047: qib7322_writeq ( qib7322, &access, QIB_7322_ahb_access_ctrl_offset ); ! 2048: } ! 2049: ! 2050: /** ! 2051: * Read data via AHB ! 2052: * ! 2053: * @v qib7322 QIB7322 device ! 2054: * @v location AHB location ! 2055: * @v data Data to read ! 2056: * @ret rc Return status code ! 2057: * ! 2058: * You must have already acquired ownership of the AHB. ! 2059: */ ! 2060: static int qib7322_ahb_read ( struct qib7322 *qib7322, unsigned int location, ! 2061: uint32_t *data ) { ! 2062: struct QIB_7322_ahb_transaction_reg xact; ! 2063: int rc; ! 2064: ! 2065: /* Initiate transaction */ ! 2066: memset ( &xact, 0, sizeof ( xact ) ); ! 2067: BIT_FILL_2 ( &xact, ! 2068: ahb_address, QIB7322_AHB_LOC_ADDRESS ( location ), ! 2069: write_not_read, 0 ); ! 2070: qib7322_writeq ( qib7322, &xact, QIB_7322_ahb_transaction_reg_offset ); ! 2071: ! 2072: /* Wait for transaction to complete */ ! 2073: if ( ( rc = qib7322_ahb_wait ( qib7322 ) ) != 0 ) ! 2074: return rc; ! 2075: ! 2076: /* Read transaction data */ ! 2077: qib7322_readq ( qib7322, &xact, QIB_7322_ahb_transaction_reg_offset ); ! 2078: *data = BIT_GET ( &xact, ahb_data ); ! 2079: return 0; ! 2080: } ! 2081: ! 2082: /** ! 2083: * Write data via AHB ! 2084: * ! 2085: * @v qib7322 QIB7322 device ! 2086: * @v location AHB location ! 2087: * @v data Data to write ! 2088: * @ret rc Return status code ! 2089: * ! 2090: * You must have already acquired ownership of the AHB. ! 2091: */ ! 2092: static int qib7322_ahb_write ( struct qib7322 *qib7322, unsigned int location, ! 2093: uint32_t data ) { ! 2094: struct QIB_7322_ahb_transaction_reg xact; ! 2095: int rc; ! 2096: ! 2097: /* Initiate transaction */ ! 2098: memset ( &xact, 0, sizeof ( xact ) ); ! 2099: BIT_FILL_3 ( &xact, ! 2100: ahb_address, QIB7322_AHB_LOC_ADDRESS ( location ), ! 2101: write_not_read, 1, ! 2102: ahb_data, data ); ! 2103: qib7322_writeq ( qib7322, &xact, QIB_7322_ahb_transaction_reg_offset ); ! 2104: ! 2105: /* Wait for transaction to complete */ ! 2106: if ( ( rc = qib7322_ahb_wait ( qib7322 ) ) != 0 ) ! 2107: return rc; ! 2108: ! 2109: return 0; ! 2110: } ! 2111: ! 2112: /** ! 2113: * Read/modify/write AHB register ! 2114: * ! 2115: * @v qib7322 QIB7322 device ! 2116: * @v location AHB location ! 2117: * @v value Value to set ! 2118: * @v mask Mask to apply to old value ! 2119: * @ret rc Return status code ! 2120: */ ! 2121: static int qib7322_ahb_mod_reg ( struct qib7322 *qib7322, unsigned int location, ! 2122: uint32_t value, uint32_t mask ) { ! 2123: uint32_t old_value; ! 2124: uint32_t new_value; ! 2125: int rc; ! 2126: ! 2127: DBG_DISABLE ( DBGLVL_IO ); ! 2128: ! 2129: /* Sanity check */ ! 2130: assert ( ( value & mask ) == value ); ! 2131: ! 2132: /* Acquire bus ownership */ ! 2133: if ( ( rc = qib7322_ahb_request ( qib7322, location ) ) != 0 ) ! 2134: goto out; ! 2135: ! 2136: /* Read existing value */ ! 2137: if ( ( rc = qib7322_ahb_read ( qib7322, location, &old_value ) ) != 0 ) ! 2138: goto out_release; ! 2139: ! 2140: /* Update value */ ! 2141: new_value = ( ( old_value & ~mask ) | value ); ! 2142: DBGCP ( qib7322, "QIB7322 %p AHB %x %#08x => %#08x\n", ! 2143: qib7322, location, old_value, new_value ); ! 2144: if ( ( rc = qib7322_ahb_write ( qib7322, location, new_value ) ) != 0 ) ! 2145: goto out_release; ! 2146: ! 2147: out_release: ! 2148: /* Release bus */ ! 2149: qib7322_ahb_release ( qib7322 ); ! 2150: out: ! 2151: DBG_ENABLE ( DBGLVL_IO ); ! 2152: return rc; ! 2153: } ! 2154: ! 2155: /** ! 2156: * Read/modify/write AHB register across all ports and channels ! 2157: * ! 2158: * @v qib7322 QIB7322 device ! 2159: * @v reg AHB register ! 2160: * @v value Value to set ! 2161: * @v mask Mask to apply to old value ! 2162: * @ret rc Return status code ! 2163: */ ! 2164: static int qib7322_ahb_mod_reg_all ( struct qib7322 *qib7322, unsigned int reg, ! 2165: uint32_t value, uint32_t mask ) { ! 2166: unsigned int port; ! 2167: unsigned int channel; ! 2168: unsigned int location; ! 2169: int rc; ! 2170: ! 2171: for ( port = 0 ; port < QIB7322_MAX_PORTS ; port++ ) { ! 2172: for ( channel = 0 ; channel < QIB7322_MAX_WIDTH ; channel++ ) { ! 2173: location = QIB7322_AHB_LOCATION ( port, channel, reg ); ! 2174: if ( ( rc = qib7322_ahb_mod_reg ( qib7322, location, ! 2175: value, mask ) ) != 0 ) ! 2176: return rc; ! 2177: } ! 2178: } ! 2179: return 0; ! 2180: } ! 2181: ! 2182: /*************************************************************************** ! 2183: * ! 2184: * Infiniband SerDes initialisation ! 2185: * ! 2186: *************************************************************************** ! 2187: */ ! 2188: ! 2189: /** ! 2190: * Initialise the IB SerDes ! 2191: * ! 2192: * @v qib7322 QIB7322 device ! 2193: * @ret rc Return status code ! 2194: */ ! 2195: static int qib7322_init_ib_serdes ( struct qib7322 *qib7322 ) { ! 2196: struct QIB_7322_IBCCtrlA_0 ibcctrla; ! 2197: struct QIB_7322_IBCCtrlB_0 ibcctrlb; ! 2198: struct QIB_7322_IBPCSConfig_0 ibpcsconfig; ! 2199: ! 2200: /* Configure sensible defaults for IBC */ ! 2201: memset ( &ibcctrla, 0, sizeof ( ibcctrla ) ); ! 2202: BIT_FILL_5 ( &ibcctrla, /* Tuning values taken from Linux driver */ ! 2203: FlowCtrlPeriod, 0x03, ! 2204: FlowCtrlWaterMark, 0x05, ! 2205: MaxPktLen, ( ( QIB7322_RECV_HEADER_SIZE + ! 2206: QIB7322_RECV_PAYLOAD_SIZE + ! 2207: 4 /* ICRC */ ) >> 2 ), ! 2208: PhyerrThreshold, 0xf, ! 2209: OverrunThreshold, 0xf ); ! 2210: qib7322_writeq ( qib7322, &ibcctrla, QIB_7322_IBCCtrlA_0_offset ); ! 2211: qib7322_writeq ( qib7322, &ibcctrla, QIB_7322_IBCCtrlA_1_offset ); ! 2212: ! 2213: /* Force SDR only to avoid needing all the DDR tuning, ! 2214: * Mellanox compatibility hacks etc. SDR is plenty for ! 2215: * boot-time operation. ! 2216: */ ! 2217: qib7322_readq ( qib7322, &ibcctrlb, QIB_7322_IBCCtrlB_0_offset ); ! 2218: BIT_SET ( &ibcctrlb, IB_ENHANCED_MODE, 0 ); ! 2219: BIT_SET ( &ibcctrlb, SD_SPEED_SDR, 1 ); ! 2220: BIT_SET ( &ibcctrlb, SD_SPEED_DDR, 0 ); ! 2221: BIT_SET ( &ibcctrlb, SD_SPEED_QDR, 0 ); ! 2222: BIT_SET ( &ibcctrlb, IB_NUM_CHANNELS, 1 ); /* 4X only */ ! 2223: BIT_SET ( &ibcctrlb, IB_LANE_REV_SUPPORTED, 0 ); ! 2224: BIT_SET ( &ibcctrlb, HRTBT_ENB, 0 ); ! 2225: BIT_SET ( &ibcctrlb, HRTBT_AUTO, 0 ); ! 2226: qib7322_writeq ( qib7322, &ibcctrlb, QIB_7322_IBCCtrlB_0_offset ); ! 2227: qib7322_writeq ( qib7322, &ibcctrlb, QIB_7322_IBCCtrlB_1_offset ); ! 2228: ! 2229: /* Tune SerDes */ ! 2230: qib7322_ahb_mod_reg_all ( qib7322, 2, 0, 0x00000e00UL ); ! 2231: ! 2232: /* Bring XGXS out of reset */ ! 2233: memset ( &ibpcsconfig, 0, sizeof ( ibpcsconfig ) ); ! 2234: qib7322_writeq ( qib7322, &ibpcsconfig, QIB_7322_IBPCSConfig_0_offset ); ! 2235: qib7322_writeq ( qib7322, &ibpcsconfig, QIB_7322_IBPCSConfig_1_offset ); ! 2236: ! 2237: return 0; ! 2238: } ! 2239: ! 2240: /*************************************************************************** ! 2241: * ! 2242: * PCI layer interface ! 2243: * ! 2244: *************************************************************************** ! 2245: */ ! 2246: ! 2247: /** ! 2248: * Reset QIB7322 ! 2249: * ! 2250: * @v qib7322 QIB7322 device ! 2251: * @v pci PCI device ! 2252: * @ret rc Return status code ! 2253: */ ! 2254: static void qib7322_reset ( struct qib7322 *qib7322, struct pci_device *pci ) { ! 2255: struct QIB_7322_Control control; ! 2256: struct pci_config_backup backup; ! 2257: ! 2258: /* Back up PCI configuration space */ ! 2259: pci_backup ( pci, &backup, NULL ); ! 2260: ! 2261: /* Assert reset */ ! 2262: memset ( &control, 0, sizeof ( control ) ); ! 2263: BIT_FILL_1 ( &control, SyncReset, 1 ); ! 2264: qib7322_writeq ( qib7322, &control, QIB_7322_Control_offset ); ! 2265: ! 2266: /* Wait for reset to complete */ ! 2267: mdelay ( 1000 ); ! 2268: ! 2269: /* Restore PCI configuration space */ ! 2270: pci_restore ( pci, &backup, NULL ); ! 2271: } ! 2272: ! 2273: /** ! 2274: * Probe PCI device ! 2275: * ! 2276: * @v pci PCI device ! 2277: * @v id PCI ID ! 2278: * @ret rc Return status code ! 2279: */ ! 2280: static int qib7322_probe ( struct pci_device *pci ) { ! 2281: struct qib7322 *qib7322; ! 2282: struct QIB_7322_Revision revision; ! 2283: struct ib_device *ibdev; ! 2284: unsigned int link_speed_supported; ! 2285: int i; ! 2286: int rc; ! 2287: ! 2288: /* Allocate QIB7322 device */ ! 2289: qib7322 = zalloc ( sizeof ( *qib7322 ) ); ! 2290: if ( ! qib7322 ) { ! 2291: rc = -ENOMEM; ! 2292: goto err_alloc_qib7322; ! 2293: } ! 2294: pci_set_drvdata ( pci, qib7322 ); ! 2295: ! 2296: /* Fix up PCI device */ ! 2297: adjust_pci_device ( pci ); ! 2298: ! 2299: /* Get PCI BARs */ ! 2300: qib7322->regs = ioremap ( pci->membase, QIB7322_BAR0_SIZE ); ! 2301: DBGC2 ( qib7322, "QIB7322 %p has BAR at %08lx\n", ! 2302: qib7322, pci->membase ); ! 2303: ! 2304: /* Reset device */ ! 2305: qib7322_reset ( qib7322, pci ); ! 2306: ! 2307: /* Print some general data */ ! 2308: qib7322_readq ( qib7322, &revision, QIB_7322_Revision_offset ); ! 2309: DBGC2 ( qib7322, "QIB7322 %p board %02lx v%ld.%ld.%ld.%ld\n", qib7322, ! 2310: BIT_GET ( &revision, BoardID ), ! 2311: BIT_GET ( &revision, R_SW ), ! 2312: BIT_GET ( &revision, R_Arch ), ! 2313: BIT_GET ( &revision, R_ChipRevMajor ), ! 2314: BIT_GET ( &revision, R_ChipRevMinor ) ); ! 2315: ! 2316: /* Initialise I2C subsystem */ ! 2317: if ( ( rc = qib7322_init_i2c ( qib7322 ) ) != 0 ) ! 2318: goto err_init_i2c; ! 2319: ! 2320: /* Read EEPROM parameters */ ! 2321: if ( ( rc = qib7322_read_eeprom ( qib7322 ) ) != 0 ) ! 2322: goto err_read_eeprom; ! 2323: ! 2324: /* Initialise send datapath */ ! 2325: if ( ( rc = qib7322_init_send ( qib7322 ) ) != 0 ) ! 2326: goto err_init_send; ! 2327: ! 2328: /* Initialise receive datapath */ ! 2329: if ( ( rc = qib7322_init_recv ( qib7322 ) ) != 0 ) ! 2330: goto err_init_recv; ! 2331: ! 2332: /* Initialise the IB SerDes */ ! 2333: if ( ( rc = qib7322_init_ib_serdes ( qib7322 ) ) != 0 ) ! 2334: goto err_init_ib_serdes; ! 2335: ! 2336: /* Allocate Infiniband devices */ ! 2337: for ( i = 0 ; i < QIB7322_MAX_PORTS ; i++ ) { ! 2338: link_speed_supported = ! 2339: qib7322_link_speed_supported ( qib7322, i ); ! 2340: if ( ! link_speed_supported ) ! 2341: continue; ! 2342: ibdev = alloc_ibdev ( 0 ); ! 2343: if ( ! ibdev ) { ! 2344: rc = -ENOMEM; ! 2345: goto err_alloc_ibdev; ! 2346: } ! 2347: qib7322->ibdev[i] = ibdev; ! 2348: ibdev->dev = &pci->dev; ! 2349: ibdev->op = &qib7322_ib_operations; ! 2350: ibdev->port = ( QIB7322_PORT_BASE + i ); ! 2351: ibdev->link_width_enabled = ibdev->link_width_supported = ! 2352: IB_LINK_WIDTH_4X; /* 1x does not work */ ! 2353: ibdev->link_speed_enabled = ibdev->link_speed_supported = ! 2354: IB_LINK_SPEED_SDR; /* to avoid need for link tuning */ ! 2355: memcpy ( &ibdev->node_guid, &qib7322->guid, ! 2356: sizeof ( ibdev->node_guid ) ); ! 2357: memcpy ( &ibdev->gid.s.guid, &qib7322->guid, ! 2358: sizeof ( ibdev->gid.s.guid ) ); ! 2359: assert ( ( ibdev->gid.s.guid.bytes[7] & i ) == 0 ); ! 2360: ibdev->gid.s.guid.bytes[7] |= i; ! 2361: ib_set_drvdata ( ibdev, qib7322 ); ! 2362: } ! 2363: ! 2364: /* Register Infiniband devices */ ! 2365: for ( i = 0 ; i < QIB7322_MAX_PORTS ; i++ ) { ! 2366: if ( ! qib7322->ibdev[i] ) ! 2367: continue; ! 2368: if ( ( rc = register_ibdev ( qib7322->ibdev[i] ) ) != 0 ) { ! 2369: DBGC ( qib7322, "QIB7322 %p port %d could not register " ! 2370: "IB device: %s\n", qib7322, i, strerror ( rc ) ); ! 2371: goto err_register_ibdev; ! 2372: } ! 2373: } ! 2374: ! 2375: return 0; ! 2376: ! 2377: i = QIB7322_MAX_PORTS; ! 2378: err_register_ibdev: ! 2379: for ( i-- ; i >= 0 ; i-- ) { ! 2380: if ( qib7322->ibdev[i] ) ! 2381: unregister_ibdev ( qib7322->ibdev[i] ); ! 2382: } ! 2383: i = QIB7322_MAX_PORTS; ! 2384: err_alloc_ibdev: ! 2385: for ( i-- ; i >= 0 ; i-- ) ! 2386: ibdev_put ( qib7322->ibdev[i] ); ! 2387: err_init_ib_serdes: ! 2388: qib7322_fini_send ( qib7322 ); ! 2389: err_init_send: ! 2390: qib7322_fini_recv ( qib7322 ); ! 2391: err_init_recv: ! 2392: err_read_eeprom: ! 2393: err_init_i2c: ! 2394: free ( qib7322 ); ! 2395: err_alloc_qib7322: ! 2396: return rc; ! 2397: } ! 2398: ! 2399: /** ! 2400: * Remove PCI device ! 2401: * ! 2402: * @v pci PCI device ! 2403: */ ! 2404: static void qib7322_remove ( struct pci_device *pci ) { ! 2405: struct qib7322 *qib7322 = pci_get_drvdata ( pci ); ! 2406: int i; ! 2407: ! 2408: for ( i = ( QIB7322_MAX_PORTS - 1 ) ; i >= 0 ; i-- ) { ! 2409: if ( qib7322->ibdev[i] ) ! 2410: unregister_ibdev ( qib7322->ibdev[i] ); ! 2411: } ! 2412: for ( i = ( QIB7322_MAX_PORTS - 1 ) ; i >= 0 ; i-- ) ! 2413: ibdev_put ( qib7322->ibdev[i] ); ! 2414: qib7322_fini_send ( qib7322 ); ! 2415: qib7322_fini_recv ( qib7322 ); ! 2416: free ( qib7322 ); ! 2417: } ! 2418: ! 2419: static struct pci_device_id qib7322_nics[] = { ! 2420: PCI_ROM ( 0x1077, 0x7322, "iba7322", "IBA7322 QDR InfiniBand HCA", 0 ), ! 2421: }; ! 2422: ! 2423: struct pci_driver qib7322_driver __pci_driver = { ! 2424: .ids = qib7322_nics, ! 2425: .id_count = ( sizeof ( qib7322_nics ) / sizeof ( qib7322_nics[0] ) ), ! 2426: .probe = qib7322_probe, ! 2427: .remove = qib7322_remove, ! 2428: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.