mirror of
https://github.com/xcat2/xNBA.git
synced 2024-12-14 07:11:32 +00:00
Updated MLX_* accessor macros to use implicit type information.
This commit is contained in:
parent
a3a91fedc1
commit
6a791649f0
39
src/drivers/net/mlx_ipoib/arbel.h
Normal file
39
src/drivers/net/mlx_ipoib/arbel.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef _ARBEL_H
|
||||
#define _ARBEL_H
|
||||
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_completion_queue_entry );
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_completion_with_error );
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_cq_ci_db_record );
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_qp_db_record );
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_send_doorbell );
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_ud_address_vector );
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_ctrl_send );
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_data_ptr );
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_next );
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_ud );
|
||||
|
||||
#define ARBELPRM_MAX_GATHER 1
|
||||
|
||||
struct arbelprm_ud_send_wqe {
|
||||
struct arbelprm_wqe_segment_next next;
|
||||
struct arbelprm_wqe_segment_ctrl_send ctrl;
|
||||
struct arbelprm_wqe_segment_ud ud;
|
||||
struct arbelprm_wqe_segment_data_ptr data[ARBELPRM_MAX_GATHER];
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
union arbelprm_completion_entry {
|
||||
struct arbelprm_completion_queue_entry normal;
|
||||
struct arbelprm_completion_with_error error;
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
union arbelprm_doorbell_record {
|
||||
struct arbelprm_cq_ci_db_record cq_ci;
|
||||
struct arbelprm_qp_db_record qp;
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
union arbelprm_doorbell_register {
|
||||
struct arbelprm_send_doorbell send;
|
||||
uint32_t dword[2];
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
#endif /* _ARBEL_H */
|
@ -143,8 +143,8 @@ struct addr_64_st {
|
||||
* This structure provides a wrapper around the autogenerated
|
||||
* pseudo_bit_t structures. It has the correct size, and also
|
||||
* encapsulates type information about the underlying pseudo_bit_t
|
||||
* structure, which allows the MLX_POPULATE etc. macros to work
|
||||
* without requiring explicit type information.
|
||||
* structure, which allows the MLX_FILL etc. macros to work without
|
||||
* requiring explicit type information.
|
||||
*/
|
||||
#define MLX_DECLARE_STRUCT( _structure ) \
|
||||
_structure { \
|
||||
@ -181,7 +181,8 @@ struct addr_64_st {
|
||||
|
||||
/** Bit mask for a field within a pseudo_bit_t structure */
|
||||
#define MLX_BIT_MASK( _structure_st, _field ) \
|
||||
( ( 1 << MLX_BIT_WIDTH ( _structure_st, _field ) ) - 1 )
|
||||
( ( ~( ( uint32_t ) 0 ) ) >> \
|
||||
( 32 - MLX_BIT_WIDTH ( _structure_st, _field ) ) )
|
||||
|
||||
/*
|
||||
* Assemble native-endian dword from named fields and values
|
||||
@ -229,46 +230,45 @@ struct addr_64_st {
|
||||
*
|
||||
*/
|
||||
|
||||
#define MLX_POPULATE( _ptr, _index, _assembled ) \
|
||||
#define MLX_FILL( _ptr, _index, _assembled ) \
|
||||
do { \
|
||||
uint32_t *__ptr = &(_ptr)->u.dwords[(_index)]; \
|
||||
uint32_t __assembled = (_assembled); \
|
||||
*__ptr = cpu_to_be32 ( __assembled ); \
|
||||
} while ( 0 )
|
||||
|
||||
#define MLX_POPULATE_1( _ptr, _index, ... ) \
|
||||
MLX_POPULATE ( _ptr, _index, \
|
||||
MLX_ASSEMBLE_1 ( MLX_PSEUDO_STRUCT ( _ptr ), \
|
||||
_index, __VA_ARGS__ ) )
|
||||
#define MLX_FILL_1( _ptr, _index, ... ) \
|
||||
MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_1 ( MLX_PSEUDO_STRUCT ( _ptr ),\
|
||||
_index, __VA_ARGS__ ) )
|
||||
|
||||
#define MLX_POPULATE_2( _ptr, _index, ... ) \
|
||||
MLX_POPULATE ( _ptr, _index, \
|
||||
MLX_ASSEMBLE_2 ( MLX_PSEUDO_STRUCT ( _ptr ), \
|
||||
_index, __VA_ARGS__ ) )
|
||||
#define MLX_FILL_2( _ptr, _index, ... ) \
|
||||
MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_2 ( MLX_PSEUDO_STRUCT ( _ptr ),\
|
||||
_index, __VA_ARGS__ ) )
|
||||
|
||||
#define MLX_POPULATE_3( _ptr, _index, ... ) \
|
||||
MLX_POPULATE ( _ptr, _index, \
|
||||
MLX_ASSEMBLE_3 ( MLX_PSEUDO_STRUCT ( _ptr ), \
|
||||
_index, __VA_ARGS__ ) )
|
||||
#define MLX_FILL_3( _ptr, _index, ... ) \
|
||||
MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_3 ( MLX_PSEUDO_STRUCT ( _ptr ),\
|
||||
_index, __VA_ARGS__ ) )
|
||||
|
||||
#define MLX_FILL_4( _ptr, _index, ... ) \
|
||||
MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_4 ( MLX_PSEUDO_STRUCT ( _ptr ),\
|
||||
_index, __VA_ARGS__ ) )
|
||||
|
||||
#define MLX_POPULATE_4( _ptr, _index, ... ) \
|
||||
MLX_POPULATE ( _ptr, _index, \
|
||||
MLX_ASSEMBLE_4 ( MLX_PSEUDO_STRUCT ( _ptr ), \
|
||||
_index, __VA_ARGS__ ) )
|
||||
|
||||
/*
|
||||
* Modify big-endian dword using named field and value
|
||||
*
|
||||
*/
|
||||
|
||||
#define MLX_MODIFY( _ptr, _index, _field, _value ) \
|
||||
#define MLX_SET( _ptr, _field, _value ) \
|
||||
do { \
|
||||
uint32_t *__ptr = &(_ptr)->u.dwords[(_index)]; \
|
||||
unsigned int __index = \
|
||||
MLX_DWORD_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ), _field ); \
|
||||
uint32_t *__ptr = &(_ptr)->u.dwords[__index]; \
|
||||
uint32_t __value = be32_to_cpu ( *__ptr ); \
|
||||
__value &= ~( MLX_MASK_1 ( MLX_PSEUDO_STRUCT ( _ptr ), \
|
||||
_index, _field ) ); \
|
||||
__index, _field ) ); \
|
||||
__value |= MLX_ASSEMBLE_1 ( MLX_PSEUDO_STRUCT ( _ptr ), \
|
||||
_index, _field, _value ); \
|
||||
__index, _field, _value ); \
|
||||
*__ptr = cpu_to_be32 ( __value ); \
|
||||
} while ( 0 )
|
||||
|
||||
@ -277,7 +277,7 @@ struct addr_64_st {
|
||||
*
|
||||
*/
|
||||
|
||||
#define MLX_EXTRACT( _ptr, _field ) \
|
||||
#define MLX_GET( _ptr, _field ) \
|
||||
( { \
|
||||
unsigned int __index = \
|
||||
MLX_DWORD_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ), _field ); \
|
||||
|
@ -37,14 +37,14 @@ struct arbel_completion_queue {
|
||||
/** Doorbell record number */
|
||||
unsigned int doorbell_idx;
|
||||
/** Completion queue entries */
|
||||
union cqe_st *cqe;
|
||||
union arbelprm_completion_entry *cqe;
|
||||
};
|
||||
|
||||
struct arbel {
|
||||
/** User Access Region */
|
||||
void *uar;
|
||||
/** Doorbell records */
|
||||
union db_record_st *db_rec;
|
||||
union arbelprm_doorbell_record *db_rec;
|
||||
};
|
||||
|
||||
|
||||
@ -157,9 +157,9 @@ static int mlx_transmit_direct ( struct net_device *netdev,
|
||||
struct ib_address_vector av = {
|
||||
.dest_qp = bcast_av->dest_qp,
|
||||
.qkey = bcast_av->qkey,
|
||||
.dlid = MLX_EXTRACT ( bav, rlid ),
|
||||
.rate = ( MLX_EXTRACT ( bav, max_stat_rate ) ? 1 : 4 ),
|
||||
.sl = MLX_EXTRACT ( bav, sl ),
|
||||
.dlid = MLX_GET ( bav, rlid ),
|
||||
.rate = ( MLX_GET ( bav, max_stat_rate ) ? 1 : 4 ),
|
||||
.sl = MLX_GET ( bav, sl ),
|
||||
.gid_present = 1,
|
||||
};
|
||||
memcpy ( &av.gid, ( ( void * ) bav ) + 16, 16 );
|
||||
@ -318,18 +318,18 @@ static struct ib_gid arbel_no_gid = {
|
||||
* @v db_reg Doorbell register structure
|
||||
* @v offset Address of doorbell
|
||||
*/
|
||||
static void arbel_ring_doorbell ( struct arbel *arbel, void *db_reg,
|
||||
static void arbel_ring_doorbell ( struct arbel *arbel,
|
||||
union arbelprm_doorbell_register *db_reg,
|
||||
unsigned int offset ) {
|
||||
uint32_t *db_reg_dword = db_reg;
|
||||
|
||||
DBG ( "arbel_ring_doorbell %08lx:%08lx to %lx\n",
|
||||
db_reg_dword[0], db_reg_dword[1],
|
||||
db_reg->dword[0], db_reg->dword[1],
|
||||
virt_to_phys ( arbel->uar + offset ) );
|
||||
|
||||
barrier();
|
||||
writel ( db_reg_dword[0], ( arbel->uar + offset + 0 ) );
|
||||
writel ( db_reg->dword[0], ( arbel->uar + offset + 0 ) );
|
||||
barrier();
|
||||
writel ( db_reg_dword[1], ( arbel->uar + offset + 4 ) );
|
||||
writel ( db_reg->dword[1], ( arbel->uar + offset + 4 ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -347,15 +347,16 @@ static int arbel_post_send ( struct ib_device *ibdev, struct io_buffer *iobuf,
|
||||
struct arbel *arbel = ibdev->priv;
|
||||
struct ib_work_queue *wq = &qp->send;
|
||||
struct arbel_send_work_queue *arbel_wq = wq->priv;
|
||||
unsigned int wqe_idx_mask = ( wq->num_wqes - 1 );
|
||||
struct ud_send_wqe_st *prev_wqe;
|
||||
struct ud_send_wqe_st *wqe;
|
||||
struct arbelprm_ud_send_wqe *prev_wqe;
|
||||
struct arbelprm_ud_send_wqe *wqe;
|
||||
union arbelprm_doorbell_record *db_rec;
|
||||
union arbelprm_doorbell_register db_reg;
|
||||
struct ib_gid *gid;
|
||||
unsigned int wqe_idx_mask;
|
||||
size_t nds;
|
||||
union db_record_st *db_rec;
|
||||
struct send_doorbell_st db_reg;
|
||||
|
||||
/* Allocate work queue entry */
|
||||
wqe_idx_mask = ( wq->num_wqes - 1 );
|
||||
if ( wq->iobufs[wq->next_idx & wqe_idx_mask] ) {
|
||||
DBGC ( arbel, "ARBEL %p send queue full", arbel );
|
||||
return -ENOBUFS;
|
||||
@ -365,69 +366,61 @@ static int arbel_post_send ( struct ib_device *ibdev, struct io_buffer *iobuf,
|
||||
wqe = &arbel_wq->wqe_u[wq->next_idx & wqe_idx_mask].wqe_cont.wqe;
|
||||
|
||||
/* Construct work queue entry */
|
||||
MLX_POPULATE_1 ( &wqe->next.next, arbelprm_wqe_segment_next_st, 1,
|
||||
always1, 1 );
|
||||
memset ( &wqe->next.control, 0,
|
||||
sizeof ( wqe->next.control ) );
|
||||
MLX_POPULATE_1 ( &wqe->next.control,
|
||||
arbelprm_wqe_segment_ctrl_send_st, 0,
|
||||
always1, 1 );
|
||||
memset ( &wqe->udseg, 0, sizeof ( wqe->udseg ) );
|
||||
MLX_POPULATE_2 ( &wqe->udseg, arbelprm_ud_address_vector_st, 0,
|
||||
pd, GLOBAL_PD,
|
||||
port_number, PXE_IB_PORT );
|
||||
MLX_POPULATE_2 ( &wqe->udseg, arbelprm_ud_address_vector_st, 1,
|
||||
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 );
|
||||
MLX_FILL_1 ( &wqe->next, 1, always1, 1 );
|
||||
memset ( &wqe->ctrl, 0, sizeof ( wqe->ctrl ) );
|
||||
MLX_FILL_1 ( &wqe->ctrl, 0, always1, 1 );
|
||||
memset ( &wqe->ud, 0, sizeof ( wqe->ud ) );
|
||||
MLX_FILL_2 ( &wqe->ud, 0,
|
||||
ud_address_vector.pd, GLOBAL_PD,
|
||||
ud_address_vector.port_number, PXE_IB_PORT );
|
||||
MLX_FILL_2 ( &wqe->ud, 1,
|
||||
ud_address_vector.rlid, av->dlid,
|
||||
ud_address_vector.g, av->gid_present );
|
||||
MLX_FILL_2 ( &wqe->ud, 2,
|
||||
ud_address_vector.max_stat_rate,
|
||||
( ( av->rate >= 3 ) ? 0 : 1 ),
|
||||
ud_address_vector.msg, 3 );
|
||||
MLX_FILL_1 ( &wqe->ud, 3, ud_address_vector.sl, av->sl );
|
||||
gid = ( av->gid_present ? &av->gid : &arbel_no_gid );
|
||||
memcpy ( ( ( ( void * ) &wqe->udseg ) + 16 ),
|
||||
gid, sizeof ( *gid ) );
|
||||
MLX_POPULATE_1 ( &wqe->udseg, arbelprm_wqe_segment_ud_st, 8,
|
||||
destination_qp, av->dest_qp );
|
||||
MLX_POPULATE_1 ( &wqe->udseg, arbelprm_wqe_segment_ud_st, 9,
|
||||
q_key, av->qkey );
|
||||
wqe->mpointer[0].local_addr_l =
|
||||
cpu_to_be32 ( virt_to_bus ( iobuf->data ) );
|
||||
wqe->mpointer[0].byte_count = cpu_to_be32 ( iob_len ( iobuf ) );
|
||||
memcpy ( &wqe->ud.u.dwords[4], gid, sizeof ( *gid ) );
|
||||
MLX_FILL_1 ( &wqe->ud, 8, destination_qp, av->dest_qp );
|
||||
MLX_FILL_1 ( &wqe->ud, 9, q_key, av->qkey );
|
||||
MLX_FILL_1 ( &wqe->data[0], 3,
|
||||
local_address_l, virt_to_bus ( iobuf->data ) );
|
||||
MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_len ( iobuf ) );
|
||||
|
||||
DBG ( "Work queue entry:\n" );
|
||||
DBG_HD ( wqe, sizeof ( *wqe ) );
|
||||
|
||||
/* Update previous work queue entry's "next" field */
|
||||
nds = ( ( offsetof ( typeof ( *wqe ), mpointer ) +
|
||||
sizeof ( wqe->mpointer[0] ) ) >> 4 );
|
||||
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 );
|
||||
nds = ( ( offsetof ( typeof ( *wqe ), data ) +
|
||||
sizeof ( wqe->data[0] ) ) >> 4 );
|
||||
MLX_SET ( &prev_wqe->next, nopcode, XDEV_NOPCODE_SEND );
|
||||
MLX_FILL_3 ( &prev_wqe->next, 1,
|
||||
nds, nds,
|
||||
f, 1,
|
||||
always1, 1 );
|
||||
|
||||
DBG ( "Previous work queue entry's next field:\n" );
|
||||
DBG_HD ( &prev_wqe->next.next, sizeof ( prev_wqe->next.next ) );
|
||||
DBG_HD ( &prev_wqe->next, sizeof ( prev_wqe->next ) );
|
||||
|
||||
/* Update doorbell record */
|
||||
db_rec = &arbel->db_rec[arbel_wq->doorbell_idx];
|
||||
MLX_POPULATE_1 ( db_rec, arbelprm_qp_db_record_st, 0,
|
||||
counter, ( ( wq->next_idx + 1 ) & 0xffff ) );
|
||||
MLX_FILL_1 ( &db_rec->qp, 0,
|
||||
counter, ( ( wq->next_idx + 1 ) & 0xffff ) );
|
||||
barrier();
|
||||
DBG ( "Doorbell record:\n" );
|
||||
DBG_HD ( db_rec, 8 );
|
||||
|
||||
/* Ring doorbell register */
|
||||
MLX_POPULATE_4 ( &db_reg, arbelprm_send_doorbell_st, 0,
|
||||
nopcode, XDEV_NOPCODE_SEND,
|
||||
f, 1,
|
||||
wqe_counter, ( wq->next_idx & 0xffff ),
|
||||
wqe_cnt, 1 );
|
||||
MLX_POPULATE_2 ( &db_reg, arbelprm_send_doorbell_st, 1,
|
||||
nds, nds,
|
||||
qpn, qp->qpn );
|
||||
MLX_FILL_4 ( &db_reg.send, 0,
|
||||
nopcode, XDEV_NOPCODE_SEND,
|
||||
f, 1,
|
||||
wqe_counter, ( wq->next_idx & 0xffff ),
|
||||
wqe_cnt, 1 );
|
||||
MLX_FILL_2 ( &db_reg.send, 1,
|
||||
nds, nds,
|
||||
qpn, qp->qpn );
|
||||
arbel_ring_doorbell ( arbel, &db_reg, POST_SND_OFFSET );
|
||||
|
||||
/* Update work queue's index */
|
||||
@ -437,13 +430,12 @@ static int arbel_post_send ( struct ib_device *ibdev, struct io_buffer *iobuf,
|
||||
}
|
||||
|
||||
static void arbel_parse_completion ( struct arbel *arbel,
|
||||
union cqe_st *cqe,
|
||||
union arbelprm_completion_entry *cqe,
|
||||
struct ib_completion *completion ) {
|
||||
memset ( completion, 0, sizeof ( *completion ) );
|
||||
is_send = MLX_EXTRACT ( cqe, arbelprm_completion_queue_entry_st, s );
|
||||
completion->len =
|
||||
MLX_EXTRACT ( cqe, arbelprm_completion_queue_entry_st,
|
||||
byte_cnt );}
|
||||
completion->is_send = MLX_GET ( &cqe->normal, s );
|
||||
completion->len = MLX_GET ( &cqe->normal, byte_cnt );
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll completion queue
|
||||
@ -459,8 +451,8 @@ static void arbel_poll_cq ( struct ib_device *ibdev,
|
||||
struct arbel *arbel = ibdev->priv;
|
||||
struct arbel_completion_queue *arbel_cq = cq->priv;
|
||||
unsigned int cqe_idx_mask = ( cq->num_cqes - 1 );
|
||||
union db_record_st *db_rec = &arbel->db_rec[arbel_cq->doorbell_idx];
|
||||
union cqe_st *cqe;
|
||||
union arbelprm_doorbell_record *db_rec;
|
||||
union arbelprm_completion_entry *cqe;
|
||||
struct ib_completion completion;
|
||||
struct io_buffer *iobuf;
|
||||
int is_send;
|
||||
@ -468,8 +460,7 @@ static void arbel_poll_cq ( struct ib_device *ibdev,
|
||||
while ( 1 ) {
|
||||
/* Look for completion entry */
|
||||
cqe = &arbel_cq->cqe[cq->next_idx & cqe_idx_mask];
|
||||
if ( MLX_EXTRACT ( cqe, arbelprm_completion_queue_entry_st,
|
||||
owner ) != 0 ) {
|
||||
if ( MLX_GET ( &cqe->normal, owner ) != 0 ) {
|
||||
/* Entry still owned by hardware; end of poll */
|
||||
break;
|
||||
}
|
||||
@ -484,14 +475,14 @@ static void arbel_poll_cq ( struct ib_device *ibdev,
|
||||
iobuf );
|
||||
|
||||
/* Return ownership to hardware */
|
||||
MLX_POPULATE_1 ( cqe, arbelprm_completion_queue_entry_st, 7,
|
||||
owner, 1 );
|
||||
MLX_FILL_1 ( &cqe->normal, 7, owner, 1 );
|
||||
barrier();
|
||||
/* Update completion queue's index */
|
||||
cq->next_idx++;
|
||||
/* Update doorbell record */
|
||||
MLX_POPULATE_1 ( db_rec, arbelprm_cq_ci_db_record_st, 0,
|
||||
counter, ( cq->next_idx & 0xffffffffUL ) );
|
||||
db_rec = &arbel->db_rec[arbel_cq->doorbell_idx];
|
||||
MLX_FILL_1 ( &db_rec->cq_ci, 0,
|
||||
counter, ( cq->next_idx & 0xffffffffUL ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,6 +113,8 @@ struct ib_completion_queue {
|
||||
|
||||
/** An Infiniband completion */
|
||||
struct ib_completion {
|
||||
/** Completion is for send queue */
|
||||
int is_send;
|
||||
/** Length */
|
||||
size_t len;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user