Annotation of qemu/roms/ipxe/src/drivers/infiniband/qib7322.c, revision 1.1

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: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.