Annotation of qemu/roms/ipxe/src/drivers/infiniband/arbel.h, revision 1.1

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

unix.superglobalmegacorp.com

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