summaryrefslogtreecommitdiffstats
path: root/src/drivers/net/mlx_ipoib/mt25218.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/net/mlx_ipoib/mt25218.c')
-rw-r--r--src/drivers/net/mlx_ipoib/mt25218.c100
1 files changed, 42 insertions, 58 deletions
diff --git a/src/drivers/net/mlx_ipoib/mt25218.c b/src/drivers/net/mlx_ipoib/mt25218.c
index c6015fb24..e8290bb63 100644
--- a/src/drivers/net/mlx_ipoib/mt25218.c
+++ b/src/drivers/net/mlx_ipoib/mt25218.c
@@ -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 = {