Now at least compiles
authorMichael Brown <mcb30@etherboot.org>
Fri, 14 Sep 2007 23:19:38 +0000 (00:19 +0100)
committerMichael Brown <mcb30@etherboot.org>
Fri, 14 Sep 2007 23:19:38 +0000 (00:19 +0100)
src/drivers/net/mlx_ipoib/bit_ops.h
src/drivers/net/mlx_ipoib/mt25218.c
src/drivers/net/mlx_ipoib/mt25218.h
src/include/gpxe/infiniband.h

index b67f92c..74823a6 100644 (file)
@@ -133,4 +133,102 @@ struct addr_64_st {
        field; \
 })
 
+
+
+/* Remaining code Copyright Fen Systems Ltd. 2007 */
+
+/** Bit offset of a field within a pseudo_bit_t structure */
+#define MLX_BIT_OFFSET( _structure, _field )                              \
+       offsetof ( struct _structure, _field )
+
+/** Bit width of a field within a pseudo_bit_t structure */
+#define MLX_BIT_WIDTH( _structure, _field )                               \
+       sizeof ( ( ( struct _structure * ) NULL )->_field )
+
+/*
+ * Assemble native-endian dword from named fields and values
+ *
+ */
+
+#define MLX_ASSEMBLE_1( _structure, _index, _field, _value )              \
+       ( (_value) <<                                                      \
+         ( MLX_BIT_OFFSET ( _structure, _field ) - ( 32 * (_index) ) ) )
+
+#define MLX_ASSEMBLE_2( _structure, _index, _field, _value, ... )         \
+       ( MLX_ASSEMBLE_1 ( _structure, _index, _field, _value ) |          \
+         MLX_ASSEMBLE_1 ( _structure, _index, __VA_ARGS__ ) )
+
+#define MLX_ASSEMBLE_3( _structure, _index, _field, _value, ... )         \
+       ( MLX_ASSEMBLE_1 ( _structure, _index, _field, _value ) |          \
+         MLX_ASSEMBLE_2 ( _structure, _index, __VA_ARGS__ ) )
+
+#define MLX_ASSEMBLE_4( _structure, _index, _field, _value, ... )         \
+       ( MLX_ASSEMBLE_1 ( _structure, _index, _field, _value ) |          \
+         MLX_ASSEMBLE_3 ( _structure, _index, __VA_ARGS__ ) )
+
+/*
+ * Build native-endian (positive) dword bitmasks from named fields
+ *
+ */
+
+#define MLX_MASK_1( _structure, _index, _field )                          \
+       MLX_ASSEMBLE_1 ( _structure, _index, _field,                       \
+                        ( ( 1 << MLX_BIT_WIDTH ( _structure,              \
+                                                 _field ) ) - 1 ) )
+
+#define MLX_MASK_2( _structure, _index, _field, ... )                     \
+       ( MLX_MASK_1 ( _structure, _index, _field ) |                      \
+         MLX_MASK_1 ( _structure, _index, __VA_ARGS__ ) )
+
+#define MLX_MASK_3( _structure, _index, _field, ... )                     \
+       ( MLX_MASK_1 ( _structure, _index, _field ) |                      \
+         MLX_MASK_2 ( _structure, _index, __VA_ARGS__ ) )
+
+#define MLX_MASK_4( _structure, _index, _field, ... )                     \
+       ( MLX_MASK_1 ( _structure, _index, _field ) |                      \
+         MLX_MASK_3 ( _structure, _index, __VA_ARGS__ ) )
+
+/*
+ * Populate big-endian dwords from named fields and values
+ *
+ */
+
+#define MLX_POPULATE( _base, _index, _assembled )                         \
+       do {                                                               \
+               uint32_t *__ptr = ( ( (uint32_t *) (_base) ) + (_index) ); \
+               uint32_t __assembled = (_assembled);                       \
+               *__ptr = cpu_to_be32 ( __assembled );                      \
+       } while ( 0 )
+
+#define MLX_POPULATE_1( _base, _structure, _index, ... )                  \
+       MLX_POPULATE ( _base, _index,                                      \
+                      MLX_ASSEMBLE_1 ( _structure, _index, __VA_ARGS__ ) )
+
+#define MLX_POPULATE_2( _base, _structure, _index, ... )                  \
+       MLX_POPULATE ( _base, _index,                                      \
+                      MLX_ASSEMBLE_2 ( _structure, _index, __VA_ARGS__ ) )
+
+#define MLX_POPULATE_3( _base, _structure, _index, ... )                  \
+       MLX_POPULATE ( _base, _index,                                      \
+                      MLX_ASSEMBLE_3 ( _structure, _index, __VA_ARGS__ ) )
+
+#define MLX_POPULATE_4( _base, _structure, _index, ... )                  \
+       MLX_POPULATE ( _base, _index,                                      \
+                      MLX_ASSEMBLE_4 ( _structure, _index, __VA_ARGS__ ) )
+
+/*
+ * Modify big-endian dword using named field and value
+ *
+ */
+
+#define MLX_MODIFY( _base, _structure, _index, _field, _value )                   \
+       do {                                                               \
+               uint32_t *__ptr = ( ( (uint32_t *) (_base) ) + (_index) ); \
+               uint32_t __value = be32_to_cpu ( *__ptr );                 \
+               __value &= ~( MLX_MASK_1 ( _structure, _index, _field ) ); \
+               __value |= MLX_ASSEMBLE_1 ( _structure, _index,            \
+                                           _field, _value );              \
+               *__ptr = cpu_to_be32 ( __value );                          \
+       } while ( 0 )
+
 #endif                         /* __bit_ops_h__ */
index c6015fb..e8290bb 100644 (file)
@@ -224,28 +224,32 @@ static struct net_device_operations mlx_operations = {
 };
 
 
+struct mlx_send_work_queue {
+       /** Doorbell number */
+       unsigned int doorbell_idx;
+       /** Work queue entries */
+       struct ud_send_wqe_st *wqe;
+};
 
-int ib_alloc_wqe ( struct ib_work_queue *wq, struct io_buffer *iobuf ) {
-       unsigned int wqe_idx;
-       unsigned int new_write_ptr;
-
-       /* Allocate queue entry */
-       wqe_idx = new_write_ptr = wq->write_ptr;
-       if ( wq->iobuf[wqe_idx] )
-               return -ENOBUFS;
-       wq->iobuf[wqe_idx] = iobuf;
+struct mlx {
+       /** User Access Region */
+       unsigned long uar;
+       /** Doorbell records */
+       union db_record_st *db_rec;
+};
 
-       /* Update write pointer */
-       new_write_ptr++;
-       new_write_ptr &= ( wq->num_wqes - 1 );
-       wq->write_ptr = new_write_ptr;
+static struct ib_gid mlx_no_gid = {
+       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }
+};
 
-       return wqe_idx;
-}
+static void mlx_ring_doorbell ( struct mlx *mlx, void *db_reg,
+                               unsigned int offset ) {
+       uint32_t *db_reg_dword = db_reg;
 
-static inline void ib_free_wqe ( struct ib_work_queue *wq, int wqe_idx ) {
-       assert ( wq->iobuf[wqe_idx] != NULL );
-       wq->iobuf[wqe_idx] = NULL;
+       barrier();
+       writel ( db_reg_dword[0], ( mlx->uar + offset + 0 ) );
+       barrier();
+       writel ( db_reg_dword[1], ( mlx->uar + offset + 4 ) );
 }
 
 static int mlx_post_send ( struct ib_device *ibdev, struct io_buffer *iobuf,
@@ -253,7 +257,7 @@ static int mlx_post_send ( struct ib_device *ibdev, struct io_buffer *iobuf,
                           struct ib_queue_pair *qp ) {
        struct mlx *mlx = ibdev->priv;
        struct ib_work_queue *wq = &qp->send;
-       struct mlx_work_queue *mlx_wq = wq->priv;
+       struct mlx_send_work_queue *mlx_wq = wq->priv;
        unsigned int wqe_idx_mask = ( wq->num_wqes - 1 );
        unsigned int prev_wqe_idx;
        struct ud_send_wqe_st *prev_wqe;
@@ -261,11 +265,12 @@ static int mlx_post_send ( struct ib_device *ibdev, struct io_buffer *iobuf,
        struct ud_send_wqe_st *wqe;
        struct ib_gid *gid;
        size_t nds;
-       struct send_doorbell_st doorbell;
+       union db_record_st *db_rec;
+       struct send_doorbell_st db_reg;
 
        /* Allocate work queue entry */
        prev_wqe_idx = wq->posted;
-       wqe_idx = ( prev_wqe_index + 1 );
+       wqe_idx = ( prev_wqe_idx + 1 );
        if ( wq->iobuf[wqe_idx & wqe_idx_mask] ) {
                DBGC ( mlx, "MLX %p send queue full", mlx );
                return -ENOBUFS;
@@ -282,16 +287,16 @@ static int mlx_post_send ( struct ib_device *ibdev, struct io_buffer *iobuf,
        memset ( &wqe->udseg, 0, sizeof ( wqe->udseg ) );
        MLX_POPULATE_2 ( &wqe->udseg, arbelprm_ud_address_vector_st, 0,
                         pd, GLOBAL_PD,
-                        port_number, mlx->port );
+                        port_number, PXE_IB_PORT );
        MLX_POPULATE_2 ( &wqe->udseg, arbelprm_ud_address_vector_st, 1,
-                        rlid, av->remote_lid,
+                        rlid, av->dlid,
                         g, av->gid_present );
        MLX_POPULATE_2 ( &wqe->udseg, arbelprm_ud_address_vector_st, 2,
                         max_stat_rate, ( ( av->rate >= 3 ) ? 0 : 1 ),
                         msg, 3 );
        MLX_POPULATE_1 ( &wqe->udseg, arbelprm_ud_address_vector_st, 3,
                         sl, av->sl );
-       gid = ( av->gid_present ? av->gid : &ib_no_gid );
+       gid = ( av->gid_present ? &av->gid : &mlx_no_gid );
        memcpy ( ( ( ( void * ) &wqe->udseg ) + 16 ),
                 gid, sizeof ( *gid ) );
        MLX_POPULATE_1 ( &wqe->udseg, arbelprm_wqe_segment_ud_st, 8,
@@ -305,55 +310,34 @@ static int mlx_post_send ( struct ib_device *ibdev, struct io_buffer *iobuf,
        /* Update previous work queue entry's "next" field */
        nds = ( offsetof ( typeof ( *wqe ), mpointer ) +
                sizeof ( wqe->mpointer[0] ) );
-       MLX_MODIFY_1 ( &prev_wqe->next.next, arbelprm_wqe_segment_next_st, 0,
-                      nopcode, XDEV_NOPCODE_SEND );
+       MLX_MODIFY ( &prev_wqe->next.next, arbelprm_wqe_segment_next_st, 0,
+                    nopcode, XDEV_NOPCODE_SEND );
        MLX_POPULATE_3 ( &prev_wqe->next.next, arbelprm_wqe_segment_next_st, 1,
                         nds, nds,
                         f, 1,
                         always1, 1 );
 
-       /* Ring doorbell */
-
-       doorbell index is a property of the queue pair
-
-
-       MLX_POPULATE_1 ( mlx_wq->send_uar_context, arbelprm_qp_db_record_st, 0, 
+       /* Update doorbell record */
+       db_rec = &mlx->db_rec[mlx_wq->doorbell_idx];
+       MLX_POPULATE_1 ( db_rec, arbelprm_qp_db_record_st, 0, 
                         counter, ( wqe_idx & 0xffff ) );
-       memset ( &doorbell, 0, sizeof ( doorbell ) );
-       MLX_POPULATE_4 ( &doorbell, arbelprm_send_doorbell_st, 0,
+       barrier();
+
+       /* Ring doorbell register */
+       MLX_POPULATE_4 ( &db_reg, arbelprm_send_doorbell_st, 0,
                         nopcode, XDEV_NOPCODE_SEND,
                         f, 1,
                         wqe_counter, ( prev_wqe_idx & 0xffff ),
                         wqe_cnt, 1 );
-       MLX_POPULATE_2 ( &doorbell, arbelprm_send_doorbell_st, 1,
+       MLX_POPULATE_2 ( &db_reg, arbelprm_send_doorbell_st, 1,
                         nds, nds,
                         qpn, qp->qpn );
-       barrier();
+       mlx_ring_doorbell ( mlx, &db_reg, POST_SND_OFFSET );
 
+       /* Update work queue's posted index */
        wq->posted = wqe_idx;
 
-
-       struct mlx_nic *mlx = netdev->priv;
-       ud_av_t av = iobuf->data;
-       ud_send_wqe_t snd_wqe;
-       int rc;
-
-       snd_wqe = alloc_send_wqe ( mlx->ipoib_qph );
-       if ( ! snd_wqe ) {
-               DBGC ( mlx, "MLX %p out of TX WQEs\n", mlx );
-               return -ENOBUFS;
-       }
-
-       prep_send_wqe_buf ( mlx->ipoib_qph, mlx->bcast_av, snd_wqe,
-                           iobuf->data, 0, iob_len ( iobuf ), 0 );
-       if ( ( rc = post_send_req ( mlx->ipoib_qph, snd_wqe, 1 ) ) != 0 ) {
-               DBGC ( mlx, "MLX %p could not post TX WQE %p: %s\n",
-                      mlx, snd_wqe, strerror ( rc ) );
-               free_wqe ( snd_wqe );
-               return rc;
-       }
-
-
+       return 0;
 }
 
 static struct ib_device_operations mlx_ib_operations = {
index 1e7c8d8..590d72f 100644 (file)
@@ -342,6 +342,24 @@ struct cq_dbell_st {
        __u8 raw[MT_STRUCT_SIZE(arbelprm_cq_cmd_doorbell_st)];
 } __attribute__ ((packed));
 
+struct qp_db_record_st {
+       __u8 raw[MT_STRUCT_SIZE(arbelprm_qp_db_record_st)];
+} __attribute__ ((packed));
+
+struct cq_arm_db_record_st {
+       __u8 raw[MT_STRUCT_SIZE(arbelprm_cq_arm_db_record_st)];
+} __attribute__ ((packed));
+
+struct cq_ci_db_record_st {
+       __u8 raw[MT_STRUCT_SIZE(arbelprm_cq_ci_db_record_st)];
+} __attribute__ ((packed));
+
+union db_record_st {
+       struct qp_db_record_st qp;
+       struct cq_arm_db_record_st cq_arm;
+       struct cq_ci_db_record_st cq_ci;
+} __attribute__ ((packed));
+
 struct mad_ifc_inprm_st {
        union mad_u mad;
 } __attribute__ ((packed));
index 22a8a98..ccb6e49 100644 (file)
@@ -61,6 +61,9 @@ struct ibhdr {
        uint16_t reserved;
 } __attribute__ (( packed ));
 
+
+
+
 /** An Infiniband Work Queue */
 struct ib_work_queue {
        /** Number of work queue entries */
@@ -70,10 +73,7 @@ struct ib_work_queue {
         * This is the index of the most recently posted entry.
         */
        unsigned int posted;
-       /** Driver-private data
-        *
-        * Typically used to hold the address of the work queue.
-        */
+       /** Driver private data */
        void *priv;
        /** I/O buffers assigned to work queue */
        struct io_buffer *iobuf[0];
@@ -87,13 +87,30 @@ struct ib_queue_pair {
        struct ib_work_queue send;
        /** Receive queue */
        struct ib_work_queue recv;
+       /** Driver private data */
+       void *priv;
 };
 
 /** An Infiniband Address Vector */
 struct ib_address_vector {
-       
+       /** Destination Queue Pair */
+       unsigned int dest_qp;
+       /** Queue key */
+       unsigned int qkey;
+       /** Destination Local ID */
+       unsigned int dlid;
+       /** Rate */
+       unsigned int rate;
+       /** Service level */
+       unsigned int sl;
+       /** GID is present */
+       unsigned int gid_present;
+       /** GID */
+       struct ib_gid gid;
 };
 
+struct ib_device;
+
 /**
  * Infiniband device operations
  *
@@ -119,7 +136,11 @@ struct ib_device_operations {
                              struct ib_queue_pair *qp );
 };
 
-
+/** An Infiniband device */
+struct ib_device {     
+       /** Driver private data */
+       void *priv;
+};