|
@@ -224,28 +224,32 @@ static struct net_device_operations mlx_operations = {
|
224
|
224
|
};
|
225
|
225
|
|
226
|
226
|
|
|
227
|
+struct mlx_send_work_queue {
|
|
228
|
+ /** Doorbell number */
|
|
229
|
+ unsigned int doorbell_idx;
|
|
230
|
+ /** Work queue entries */
|
|
231
|
+ struct ud_send_wqe_st *wqe;
|
|
232
|
+};
|
227
|
233
|
|
228
|
|
-int ib_alloc_wqe ( struct ib_work_queue *wq, struct io_buffer *iobuf ) {
|
229
|
|
- unsigned int wqe_idx;
|
230
|
|
- unsigned int new_write_ptr;
|
231
|
|
-
|
232
|
|
- /* Allocate queue entry */
|
233
|
|
- wqe_idx = new_write_ptr = wq->write_ptr;
|
234
|
|
- if ( wq->iobuf[wqe_idx] )
|
235
|
|
- return -ENOBUFS;
|
236
|
|
- wq->iobuf[wqe_idx] = iobuf;
|
|
234
|
+struct mlx {
|
|
235
|
+ /** User Access Region */
|
|
236
|
+ unsigned long uar;
|
|
237
|
+ /** Doorbell records */
|
|
238
|
+ union db_record_st *db_rec;
|
|
239
|
+};
|
237
|
240
|
|
238
|
|
- /* Update write pointer */
|
239
|
|
- new_write_ptr++;
|
240
|
|
- new_write_ptr &= ( wq->num_wqes - 1 );
|
241
|
|
- wq->write_ptr = new_write_ptr;
|
|
241
|
+static struct ib_gid mlx_no_gid = {
|
|
242
|
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }
|
|
243
|
+};
|
242
|
244
|
|
243
|
|
- return wqe_idx;
|
244
|
|
-}
|
|
245
|
+static void mlx_ring_doorbell ( struct mlx *mlx, void *db_reg,
|
|
246
|
+ unsigned int offset ) {
|
|
247
|
+ uint32_t *db_reg_dword = db_reg;
|
245
|
248
|
|
246
|
|
-static inline void ib_free_wqe ( struct ib_work_queue *wq, int wqe_idx ) {
|
247
|
|
- assert ( wq->iobuf[wqe_idx] != NULL );
|
248
|
|
- wq->iobuf[wqe_idx] = NULL;
|
|
249
|
+ barrier();
|
|
250
|
+ writel ( db_reg_dword[0], ( mlx->uar + offset + 0 ) );
|
|
251
|
+ barrier();
|
|
252
|
+ writel ( db_reg_dword[1], ( mlx->uar + offset + 4 ) );
|
249
|
253
|
}
|
250
|
254
|
|
251
|
255
|
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,
|
253
|
257
|
struct ib_queue_pair *qp ) {
|
254
|
258
|
struct mlx *mlx = ibdev->priv;
|
255
|
259
|
struct ib_work_queue *wq = &qp->send;
|
256
|
|
- struct mlx_work_queue *mlx_wq = wq->priv;
|
|
260
|
+ struct mlx_send_work_queue *mlx_wq = wq->priv;
|
257
|
261
|
unsigned int wqe_idx_mask = ( wq->num_wqes - 1 );
|
258
|
262
|
unsigned int prev_wqe_idx;
|
259
|
263
|
struct ud_send_wqe_st *prev_wqe;
|
|
@@ -261,11 +265,12 @@ static int mlx_post_send ( struct ib_device *ibdev, struct io_buffer *iobuf,
|
261
|
265
|
struct ud_send_wqe_st *wqe;
|
262
|
266
|
struct ib_gid *gid;
|
263
|
267
|
size_t nds;
|
264
|
|
- struct send_doorbell_st doorbell;
|
|
268
|
+ union db_record_st *db_rec;
|
|
269
|
+ struct send_doorbell_st db_reg;
|
265
|
270
|
|
266
|
271
|
/* Allocate work queue entry */
|
267
|
272
|
prev_wqe_idx = wq->posted;
|
268
|
|
- wqe_idx = ( prev_wqe_index + 1 );
|
|
273
|
+ wqe_idx = ( prev_wqe_idx + 1 );
|
269
|
274
|
if ( wq->iobuf[wqe_idx & wqe_idx_mask] ) {
|
270
|
275
|
DBGC ( mlx, "MLX %p send queue full", mlx );
|
271
|
276
|
return -ENOBUFS;
|
|
@@ -282,16 +287,16 @@ static int mlx_post_send ( struct ib_device *ibdev, struct io_buffer *iobuf,
|
282
|
287
|
memset ( &wqe->udseg, 0, sizeof ( wqe->udseg ) );
|
283
|
288
|
MLX_POPULATE_2 ( &wqe->udseg, arbelprm_ud_address_vector_st, 0,
|
284
|
289
|
pd, GLOBAL_PD,
|
285
|
|
- port_number, mlx->port );
|
|
290
|
+ port_number, PXE_IB_PORT );
|
286
|
291
|
MLX_POPULATE_2 ( &wqe->udseg, arbelprm_ud_address_vector_st, 1,
|
287
|
|
- rlid, av->remote_lid,
|
|
292
|
+ rlid, av->dlid,
|
288
|
293
|
g, av->gid_present );
|
289
|
294
|
MLX_POPULATE_2 ( &wqe->udseg, arbelprm_ud_address_vector_st, 2,
|
290
|
295
|
max_stat_rate, ( ( av->rate >= 3 ) ? 0 : 1 ),
|
291
|
296
|
msg, 3 );
|
292
|
297
|
MLX_POPULATE_1 ( &wqe->udseg, arbelprm_ud_address_vector_st, 3,
|
293
|
298
|
sl, av->sl );
|
294
|
|
- gid = ( av->gid_present ? av->gid : &ib_no_gid );
|
|
299
|
+ gid = ( av->gid_present ? &av->gid : &mlx_no_gid );
|
295
|
300
|
memcpy ( ( ( ( void * ) &wqe->udseg ) + 16 ),
|
296
|
301
|
gid, sizeof ( *gid ) );
|
297
|
302
|
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,
|
305
|
310
|
/* Update previous work queue entry's "next" field */
|
306
|
311
|
nds = ( offsetof ( typeof ( *wqe ), mpointer ) +
|
307
|
312
|
sizeof ( wqe->mpointer[0] ) );
|
308
|
|
- MLX_MODIFY_1 ( &prev_wqe->next.next, arbelprm_wqe_segment_next_st, 0,
|
309
|
|
- nopcode, XDEV_NOPCODE_SEND );
|
|
313
|
+ MLX_MODIFY ( &prev_wqe->next.next, arbelprm_wqe_segment_next_st, 0,
|
|
314
|
+ nopcode, XDEV_NOPCODE_SEND );
|
310
|
315
|
MLX_POPULATE_3 ( &prev_wqe->next.next, arbelprm_wqe_segment_next_st, 1,
|
311
|
316
|
nds, nds,
|
312
|
317
|
f, 1,
|
313
|
318
|
always1, 1 );
|
314
|
319
|
|
315
|
|
- /* Ring doorbell */
|
316
|
|
-
|
317
|
|
- doorbell index is a property of the queue pair
|
318
|
|
-
|
319
|
|
-
|
320
|
|
- MLX_POPULATE_1 ( mlx_wq->send_uar_context, arbelprm_qp_db_record_st, 0,
|
|
320
|
+ /* Update doorbell record */
|
|
321
|
+ db_rec = &mlx->db_rec[mlx_wq->doorbell_idx];
|
|
322
|
+ MLX_POPULATE_1 ( db_rec, arbelprm_qp_db_record_st, 0,
|
321
|
323
|
counter, ( wqe_idx & 0xffff ) );
|
322
|
|
- memset ( &doorbell, 0, sizeof ( doorbell ) );
|
323
|
|
- MLX_POPULATE_4 ( &doorbell, arbelprm_send_doorbell_st, 0,
|
|
324
|
+ barrier();
|
|
325
|
+
|
|
326
|
+ /* Ring doorbell register */
|
|
327
|
+ MLX_POPULATE_4 ( &db_reg, arbelprm_send_doorbell_st, 0,
|
324
|
328
|
nopcode, XDEV_NOPCODE_SEND,
|
325
|
329
|
f, 1,
|
326
|
330
|
wqe_counter, ( prev_wqe_idx & 0xffff ),
|
327
|
331
|
wqe_cnt, 1 );
|
328
|
|
- MLX_POPULATE_2 ( &doorbell, arbelprm_send_doorbell_st, 1,
|
|
332
|
+ MLX_POPULATE_2 ( &db_reg, arbelprm_send_doorbell_st, 1,
|
329
|
333
|
nds, nds,
|
330
|
334
|
qpn, qp->qpn );
|
331
|
|
- barrier();
|
|
335
|
+ mlx_ring_doorbell ( mlx, &db_reg, POST_SND_OFFSET );
|
332
|
336
|
|
|
337
|
+ /* Update work queue's posted index */
|
333
|
338
|
wq->posted = wqe_idx;
|
334
|
339
|
|
335
|
|
-
|
336
|
|
- struct mlx_nic *mlx = netdev->priv;
|
337
|
|
- ud_av_t av = iobuf->data;
|
338
|
|
- ud_send_wqe_t snd_wqe;
|
339
|
|
- int rc;
|
340
|
|
-
|
341
|
|
- snd_wqe = alloc_send_wqe ( mlx->ipoib_qph );
|
342
|
|
- if ( ! snd_wqe ) {
|
343
|
|
- DBGC ( mlx, "MLX %p out of TX WQEs\n", mlx );
|
344
|
|
- return -ENOBUFS;
|
345
|
|
- }
|
346
|
|
-
|
347
|
|
- prep_send_wqe_buf ( mlx->ipoib_qph, mlx->bcast_av, snd_wqe,
|
348
|
|
- iobuf->data, 0, iob_len ( iobuf ), 0 );
|
349
|
|
- if ( ( rc = post_send_req ( mlx->ipoib_qph, snd_wqe, 1 ) ) != 0 ) {
|
350
|
|
- DBGC ( mlx, "MLX %p could not post TX WQE %p: %s\n",
|
351
|
|
- mlx, snd_wqe, strerror ( rc ) );
|
352
|
|
- free_wqe ( snd_wqe );
|
353
|
|
- return rc;
|
354
|
|
- }
|
355
|
|
-
|
356
|
|
-
|
|
340
|
+ return 0;
|
357
|
341
|
}
|
358
|
342
|
|
359
|
343
|
static struct ib_device_operations mlx_ib_operations = {
|