Browse Source

Now handling TX completions in our poll loop.

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
08e8dfd801
3 changed files with 74 additions and 75 deletions
  1. 64
    49
      src/drivers/net/mlx_ipoib/mt25218.c
  2. 7
    12
      src/include/gpxe/infiniband.h
  3. 3
    14
      src/net/infiniband.c

+ 64
- 49
src/drivers/net/mlx_ipoib/mt25218.c View File

16
 #include <gpxe/netdevice.h>
16
 #include <gpxe/netdevice.h>
17
 #include <gpxe/infiniband.h>
17
 #include <gpxe/infiniband.h>
18
 
18
 
19
-struct mlx_nic {
20
-};
21
-
22
 /* to get some global routines like printf */
19
 /* to get some global routines like printf */
23
 #include "etherboot.h"
20
 #include "etherboot.h"
24
 /* to get the interface to the body of the program */
21
 /* to get the interface to the body of the program */
27
 #include "mt_version.c"
24
 #include "mt_version.c"
28
 #include "mt25218_imp.c"
25
 #include "mt25218_imp.c"
29
 
26
 
27
+struct mlx_nic {
28
+	/** Queue pair handle */
29
+	udqp_t ipoib_qph;
30
+	/** Broadcast Address Vector */
31
+	ud_av_t bcast_av;
32
+	/** Send completion queue */
33
+	cq_t snd_cqh;
34
+	/** Receive completion queue */
35
+	cq_t rcv_cqh;
36
+};
30
 
37
 
31
 int prompt_key(int secs, unsigned char *ch_p)
38
 int prompt_key(int secs, unsigned char *ch_p)
32
 {
39
 {
192
  */
199
  */
193
 static int mlx_transmit ( struct net_device *netdev,
200
 static int mlx_transmit ( struct net_device *netdev,
194
 			  struct io_buffer *iobuf ) {
201
 			  struct io_buffer *iobuf ) {
195
-	struct ibhdr *ibhdr = iobuf->data;
202
+	struct mlx_nic *mlx = netdev->priv;
203
+	ud_send_wqe_t snd_wqe;
204
+	int rc;
205
+
206
+	snd_wqe = alloc_send_wqe ( mlx->ipoib_qph );
207
+	if ( ! snd_wqe ) {
208
+		DBGC ( mlx, "MLX %p out of TX WQEs\n", mlx );
209
+		return -ENOBUFS;
210
+	}
211
+
212
+	prep_send_wqe_buf ( mlx->ipoib_qph, mlx->bcast_av, snd_wqe,
213
+			    iobuf->data, 0, iob_len ( iobuf ), 0 );
214
+	if ( ( rc = post_send_req ( mlx->ipoib_qph, snd_wqe, 1 ) ) != 0 ) {
215
+		DBGC ( mlx, "MLX %p could not post TX WQE %p: %s\n",
216
+		       mlx, snd_wqe, strerror ( rc ) );
217
+		free_wqe ( snd_wqe );
218
+		return rc;
219
+	}
220
+
221
+	return 0;
196
 
222
 
223
+#if 0
197
 	( void ) netdev;
224
 	( void ) netdev;
198
 
225
 
199
 	iob_pull ( iobuf, sizeof ( *ibhdr ) );	
226
 	iob_pull ( iobuf, sizeof ( *ibhdr ) );	
208
 					   ntohs ( ibhdr->proto ),
235
 					   ntohs ( ibhdr->proto ),
209
 					   iobuf->data, iob_len ( iobuf ) );
236
 					   iobuf->data, iob_len ( iobuf ) );
210
 	}
237
 	}
238
+#endif
211
 }
239
 }
212
 
240
 
213
 /**
241
 /**
214
  * Handle TX completion
242
  * Handle TX completion
215
  *
243
  *
216
  * @v netdev		Network device
244
  * @v netdev		Network device
217
- * @v cqe		Completion queue entry
245
+ * @v ib_cqe		Completion queue entry
218
  */
246
  */
219
 static void mlx_tx_complete ( struct net_device *netdev,
247
 static void mlx_tx_complete ( struct net_device *netdev,
220
-			      struct ib_cqe_st *cqe ) {
248
+			      struct ib_cqe_st *ib_cqe ) {
221
 	netdev_tx_complete_next_err ( netdev,
249
 	netdev_tx_complete_next_err ( netdev,
222
-				      ( cqe->is_error ? -EIO : 0 ) );
250
+				      ( ib_cqe->is_error ? -EIO : 0 ) );
223
 }
251
 }
224
 
252
 
225
 /**
253
 /**
226
  * Handle RX completion
254
  * Handle RX completion
227
  *
255
  *
228
  * @v netdev		Network device
256
  * @v netdev		Network device
229
- * @v cqe		Completion queue entry
257
+ * @v ib_cqe		Completion queue entry
230
  */
258
  */
231
 static void mlx_rx_complete ( struct net_device *netdev,
259
 static void mlx_rx_complete ( struct net_device *netdev,
232
-			      struct ib_cqe_st *cqe ) {
260
+			      struct ib_cqe_st *ib_cqe ) {
233
 	unsigned int len;
261
 	unsigned int len;
234
 	struct io_buffer *iobuf;
262
 	struct io_buffer *iobuf;
235
 	void *buf;
263
 	void *buf;
236
 
264
 
237
 	/* Check for errors */
265
 	/* Check for errors */
238
-	if ( cqe->is_error ) {
266
+	if ( ib_cqe->is_error ) {
239
 		netdev_rx_err ( netdev, NULL, -EIO );
267
 		netdev_rx_err ( netdev, NULL, -EIO );
240
 		return;
268
 		return;
241
 	}
269
 	}
242
 
270
 
243
 	/* Allocate I/O buffer */
271
 	/* Allocate I/O buffer */
244
-	len = cqe->count;
272
+	len = ( ib_cqe->count - GRH_SIZE );
245
 	iobuf = alloc_iob ( len );
273
 	iobuf = alloc_iob ( len );
246
 	if ( ! iobuf ) {
274
 	if ( ! iobuf ) {
247
 		netdev_rx_err ( netdev, NULL, -ENOMEM );
275
 		netdev_rx_err ( netdev, NULL, -ENOMEM );
248
 		return;
276
 		return;
249
 	}
277
 	}
250
-	buf = get_rcv_wqe_buf ( cqe->wqe, 1 );
278
+	buf = get_rcv_wqe_buf ( ib_cqe->wqe, 1 );
251
 	memcpy ( iob_put ( iobuf, len ), buf, len );
279
 	memcpy ( iob_put ( iobuf, len ), buf, len );
252
 	//	DBG ( "Received packet header:\n" );
280
 	//	DBG ( "Received packet header:\n" );
253
 	//	struct recv_wqe_st *rcv_wqe = ib_cqe.wqe;
281
 	//	struct recv_wqe_st *rcv_wqe = ib_cqe.wqe;
263
  *
291
  *
264
  * @v netdev		Network device
292
  * @v netdev		Network device
265
  * @v cq		Completion queue
293
  * @v cq		Completion queue
294
+ * @v handler		Completion handler
266
  */
295
  */
267
-static void mlx_poll_cq ( struct net_device *netdev,
268
-			  struct cq_st *cq ) {
296
+static void mlx_poll_cq ( struct net_device *netdev, cq_t cq,
297
+			  void ( * handler ) ( struct net_device *netdev,
298
+					       struct ib_cqe_st *ib_cqe ) ) {
269
 	struct mlx_nic *mlx = netdev->priv;
299
 	struct mlx_nic *mlx = netdev->priv;
270
-	struct ib_cqe_st cqe;
300
+	struct ib_cqe_st ib_cqe;
271
 	uint8_t num_cqes;
301
 	uint8_t num_cqes;
272
 
302
 
273
 	while ( 1 ) {
303
 	while ( 1 ) {
274
 
304
 
275
-		unsigned long cons_idx;
276
-		union cqe_st *temp;
277
-
278
-		cons_idx = ( cq->cons_counter & ( cq->num_cqes - 1 ) );
279
-		temp = &cq->cq_buf[cons_idx];
280
-		if ( EX_FLD_BE ( temp, arbelprm_completion_queue_entry_st,
281
-				 owner ) == 0 ) {
282
-			DBG ( "software owned\n" );
283
-			DBGC_HD ( mlx, temp, sizeof ( *temp ) );
284
-			DBG ( "my_qpn=%lx, g=%ld, s=%ld, op=%02lx, cnt=%lx\n",
285
-			      EX_FLD_BE ( temp, arbelprm_completion_queue_entry_st, my_qpn ),
286
-			      EX_FLD_BE ( temp, arbelprm_completion_queue_entry_st, g ),
287
-			      EX_FLD_BE ( temp, arbelprm_completion_queue_entry_st, s ),
288
-			      EX_FLD_BE ( temp, arbelprm_completion_queue_entry_st, opcode ),
289
-			      EX_FLD_BE ( temp, arbelprm_completion_queue_entry_st, byte_cnt ) );
290
-		}
291
-
292
 		/* Poll for single completion queue entry */
305
 		/* Poll for single completion queue entry */
293
-		ib_poll_cq ( cq, &cqe, &num_cqes );
306
+		ib_poll_cq ( cq, &ib_cqe, &num_cqes );
294
 
307
 
295
 		/* Return if no entries in the queue */
308
 		/* Return if no entries in the queue */
296
 		if ( ! num_cqes )
309
 		if ( ! num_cqes )
297
 			return;
310
 			return;
298
 
311
 
299
 		DBGC ( mlx, "MLX %p cpl in %p: err %x send %x "
312
 		DBGC ( mlx, "MLX %p cpl in %p: err %x send %x "
300
-		       "wqe %p count %lx\n", mlx, cq, cqe.is_error,
301
-		       cqe.is_send, cqe.wqe, cqe.count );
313
+		       "wqe %p count %lx\n", mlx, cq, ib_cqe.is_error,
314
+		       ib_cqe.is_send, ib_cqe.wqe, ib_cqe.count );
302
 
315
 
303
 		/* Handle TX/RX completion */
316
 		/* Handle TX/RX completion */
304
-		if ( cqe.is_send ) {
305
-			mlx_tx_complete ( netdev, &cqe );
306
-		} else {
307
-			mlx_rx_complete ( netdev, &cqe );
308
-		}
309
-		
317
+		handler ( netdev, &ib_cqe );
318
+
310
 		/* Free associated work queue entry */
319
 		/* Free associated work queue entry */
311
-		free_wqe ( cqe.wqe );
320
+		free_wqe ( ib_cqe.wqe );
312
 	}
321
 	}
313
 }
322
 }
314
 
323
 
318
  * @v netdev		Network device
327
  * @v netdev		Network device
319
  */
328
  */
320
 static void mlx_poll ( struct net_device *netdev ) {
329
 static void mlx_poll ( struct net_device *netdev ) {
330
+	struct mlx_nic *mlx = netdev->priv;
321
 	int rc;
331
 	int rc;
322
 
332
 
323
 	if ( ( rc = poll_error_buf() ) != 0 ) {
333
 	if ( ( rc = poll_error_buf() ) != 0 ) {
330
 		return;
340
 		return;
331
 	}
341
 	}
332
 
342
 
333
-	//	mlx_poll_cq ( netdev, ipoib_data.snd_cqh );
334
-	mlx_poll_cq ( netdev, ipoib_data.rcv_cqh );
343
+	mlx_poll_cq ( netdev, mlx->snd_cqh, mlx_tx_complete );
344
+	mlx_poll_cq ( netdev, mlx->rcv_cqh, mlx_rx_complete );
335
 }
345
 }
336
 
346
 
337
 /**
347
 /**
386
 	struct net_device *netdev = pci_get_drvdata ( pci );
396
 	struct net_device *netdev = pci_get_drvdata ( pci );
387
 
397
 
388
 	unregister_netdev ( netdev );
398
 	unregister_netdev ( netdev );
389
-	ipoib_close(0);
399
+	ib_driver_close ( 0 );
390
 	netdev_nullify ( netdev );
400
 	netdev_nullify ( netdev );
391
 	netdev_put ( netdev );
401
 	netdev_put ( netdev );
392
 }
402
 }
473
 	struct net_device *netdev;
483
 	struct net_device *netdev;
474
 	struct mlx_nic *mlx;
484
 	struct mlx_nic *mlx;
475
 	struct ib_mac *mac;
485
 	struct ib_mac *mac;
486
+	udqp_t qph;
476
 	int rc;
487
 	int rc;
477
 
488
 
478
 	/* Allocate net device */
489
 	/* Allocate net device */
489
 	adjust_pci_device ( pci );
500
 	adjust_pci_device ( pci );
490
 
501
 
491
 	/* Initialise hardware */
502
 	/* Initialise hardware */
492
-	if ( ( rc = ipoib_init ( pci ) ) != 0 )
503
+	if ( ( rc = ib_driver_init ( pci, &qph ) ) != 0 )
493
 		goto err_ipoib_init;
504
 		goto err_ipoib_init;
505
+	mlx->ipoib_qph = qph;
506
+	mlx->bcast_av = ib_data.bcast_av;
507
+	mlx->snd_cqh = ib_data.ipoib_snd_cq;
508
+	mlx->rcv_cqh = ib_data.ipoib_rcv_cq;
494
 	mac = ( ( struct ib_mac * ) netdev->ll_addr );
509
 	mac = ( ( struct ib_mac * ) netdev->ll_addr );
495
-	mac->qpn = htonl ( ipoib_data.ipoib_qpn );
496
-	memcpy ( &mac->gid, ipoib_data.port_gid_raw, sizeof ( mac->gid ) );
510
+	mac->qpn = htonl ( ib_get_qpn ( mlx->ipoib_qph ) );
511
+	memcpy ( &mac->gid, ib_data.port_gid.raw, sizeof ( mac->gid ) );
497
 
512
 
498
 	/* Register network device */
513
 	/* Register network device */
499
 	if ( ( rc = register_netdev ( netdev ) ) != 0 )
514
 	if ( ( rc = register_netdev ( netdev ) ) != 0 )
503
 
518
 
504
  err_register_netdev:
519
  err_register_netdev:
505
  err_ipoib_init:
520
  err_ipoib_init:
506
-	ipoib_close(0);
521
+	ib_driver_close ( 0 );
507
 	netdev_nullify ( netdev );
522
 	netdev_nullify ( netdev );
508
 	netdev_put ( netdev );
523
 	netdev_put ( netdev );
509
 	return rc;
524
 	return rc;

+ 7
- 12
src/include/gpxe/infiniband.h View File

10
 #include <stdint.h>
10
 #include <stdint.h>
11
 #include <gpxe/netdevice.h>
11
 #include <gpxe/netdevice.h>
12
 
12
 
13
-/** Infiniband hardware address length */
14
-#define IB_ALEN 20
15
-#define IB_HLEN 24
16
-
17
 /** An Infiniband Global Identifier */
13
 /** An Infiniband Global Identifier */
18
 struct ib_gid {
14
 struct ib_gid {
19
 	uint8_t bytes[16];
15
 	uint8_t bytes[16];
40
 	struct ib_gid dgid;
36
 	struct ib_gid dgid;
41
 } __attribute__ (( packed ));
37
 } __attribute__ (( packed ));
42
 
38
 
39
+/** Infiniband MAC address length */
40
+#define IB_ALEN 20
41
+
43
 /** An Infiniband MAC address */
42
 /** An Infiniband MAC address */
44
 struct ib_mac {
43
 struct ib_mac {
45
 	/** Queue pair number
44
 	/** Queue pair number
51
 	struct ib_gid gid;
50
 	struct ib_gid gid;
52
 } __attribute__ (( packed ));
51
 } __attribute__ (( packed ));
53
 
52
 
54
-/** An Infiniband header
55
- *
56
- * This data structure doesn't represent the on-wire format, but does
57
- * contain all the information required by the driver to construct the
58
- * packet.
59
- */
53
+/** Infiniband link-layer header length */
54
+#define IB_HLEN 4
55
+
56
+/** An Infiniband link-layer header */
60
 struct ibhdr {
57
 struct ibhdr {
61
-	/** Peer address */
62
-	uint8_t peer[IB_ALEN];
63
 	/** Network-layer protocol */
58
 	/** Network-layer protocol */
64
 	uint16_t proto;
59
 	uint16_t proto;
65
 	/** Reserved, must be zero */
60
 	/** Reserved, must be zero */

+ 3
- 14
src/net/infiniband.c View File

50
 		   struct net_protocol *net_protocol, const void *ll_dest ) {
50
 		   struct net_protocol *net_protocol, const void *ll_dest ) {
51
 	struct ibhdr *ibhdr = iob_push ( iobuf, sizeof ( *ibhdr ) );
51
 	struct ibhdr *ibhdr = iob_push ( iobuf, sizeof ( *ibhdr ) );
52
 
52
 
53
-
54
 	/* Build Infiniband header */
53
 	/* Build Infiniband header */
55
-	memcpy ( ibhdr->peer, ll_dest, IB_ALEN );
56
 	ibhdr->proto = net_protocol->net_proto;
54
 	ibhdr->proto = net_protocol->net_proto;
57
 	ibhdr->reserved = 0;
55
 	ibhdr->reserved = 0;
58
 
56
 
57
+	( void ) ll_dest;
58
+
59
 	/* Hand off to network device */
59
 	/* Hand off to network device */
60
 	return netdev_tx ( netdev, iobuf );
60
 	return netdev_tx ( netdev, iobuf );
61
 }
61
 }
70
  * network-layer protocol.
70
  * network-layer protocol.
71
  */
71
  */
72
 static int ib_rx ( struct io_buffer *iobuf, struct net_device *netdev ) {
72
 static int ib_rx ( struct io_buffer *iobuf, struct net_device *netdev ) {
73
-
74
-	struct {
75
-		uint16_t proto;
76
-		uint16_t reserved;
77
-	} * header = iobuf->data;
78
-
79
-	iob_pull ( iobuf, sizeof ( *header ) );
80
-	return net_rx ( iobuf, netdev, header->proto, NULL );
81
-
82
-
83
-
84
 	struct ibhdr *ibhdr = iobuf->data;
73
 	struct ibhdr *ibhdr = iobuf->data;
85
 
74
 
86
 	/* Sanity check */
75
 	/* Sanity check */
95
 	iob_pull ( iobuf, sizeof ( *ibhdr ) );
84
 	iob_pull ( iobuf, sizeof ( *ibhdr ) );
96
 
85
 
97
 	/* Hand off to network-layer protocol */
86
 	/* Hand off to network-layer protocol */
98
-	return net_rx ( iobuf, netdev, ibhdr->proto, ibhdr->peer );
87
+	return net_rx ( iobuf, netdev, ibhdr->proto, NULL );
99
 }
88
 }
100
 
89
 
101
 /**
90
 /**

Loading…
Cancel
Save