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,9 +16,6 @@ Skeleton NIC driver for Etherboot
16 16
 #include <gpxe/netdevice.h>
17 17
 #include <gpxe/infiniband.h>
18 18
 
19
-struct mlx_nic {
20
-};
21
-
22 19
 /* to get some global routines like printf */
23 20
 #include "etherboot.h"
24 21
 /* to get the interface to the body of the program */
@@ -27,6 +24,16 @@ struct mlx_nic {
27 24
 #include "mt_version.c"
28 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 38
 int prompt_key(int secs, unsigned char *ch_p)
32 39
 {
@@ -192,8 +199,28 @@ static uint8_t ib_broadcast[IB_ALEN] = { 0xff, };
192 199
  */
193 200
 static int mlx_transmit ( struct net_device *netdev,
194 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 224
 	( void ) netdev;
198 225
 
199 226
 	iob_pull ( iobuf, sizeof ( *ibhdr ) );	
@@ -208,46 +235,47 @@ static int mlx_transmit ( struct net_device *netdev,
208 235
 					   ntohs ( ibhdr->proto ),
209 236
 					   iobuf->data, iob_len ( iobuf ) );
210 237
 	}
238
+#endif
211 239
 }
212 240
 
213 241
 /**
214 242
  * Handle TX completion
215 243
  *
216 244
  * @v netdev		Network device
217
- * @v cqe		Completion queue entry
245
+ * @v ib_cqe		Completion queue entry
218 246
  */
219 247
 static void mlx_tx_complete ( struct net_device *netdev,
220
-			      struct ib_cqe_st *cqe ) {
248
+			      struct ib_cqe_st *ib_cqe ) {
221 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 254
  * Handle RX completion
227 255
  *
228 256
  * @v netdev		Network device
229
- * @v cqe		Completion queue entry
257
+ * @v ib_cqe		Completion queue entry
230 258
  */
231 259
 static void mlx_rx_complete ( struct net_device *netdev,
232
-			      struct ib_cqe_st *cqe ) {
260
+			      struct ib_cqe_st *ib_cqe ) {
233 261
 	unsigned int len;
234 262
 	struct io_buffer *iobuf;
235 263
 	void *buf;
236 264
 
237 265
 	/* Check for errors */
238
-	if ( cqe->is_error ) {
266
+	if ( ib_cqe->is_error ) {
239 267
 		netdev_rx_err ( netdev, NULL, -EIO );
240 268
 		return;
241 269
 	}
242 270
 
243 271
 	/* Allocate I/O buffer */
244
-	len = cqe->count;
272
+	len = ( ib_cqe->count - GRH_SIZE );
245 273
 	iobuf = alloc_iob ( len );
246 274
 	if ( ! iobuf ) {
247 275
 		netdev_rx_err ( netdev, NULL, -ENOMEM );
248 276
 		return;
249 277
 	}
250
-	buf = get_rcv_wqe_buf ( cqe->wqe, 1 );
278
+	buf = get_rcv_wqe_buf ( ib_cqe->wqe, 1 );
251 279
 	memcpy ( iob_put ( iobuf, len ), buf, len );
252 280
 	//	DBG ( "Received packet header:\n" );
253 281
 	//	struct recv_wqe_st *rcv_wqe = ib_cqe.wqe;
@@ -263,52 +291,33 @@ static void mlx_rx_complete ( struct net_device *netdev,
263 291
  *
264 292
  * @v netdev		Network device
265 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 299
 	struct mlx_nic *mlx = netdev->priv;
270
-	struct ib_cqe_st cqe;
300
+	struct ib_cqe_st ib_cqe;
271 301
 	uint8_t num_cqes;
272 302
 
273 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 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 308
 		/* Return if no entries in the queue */
296 309
 		if ( ! num_cqes )
297 310
 			return;
298 311
 
299 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 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 319
 		/* Free associated work queue entry */
311
-		free_wqe ( cqe.wqe );
320
+		free_wqe ( ib_cqe.wqe );
312 321
 	}
313 322
 }
314 323
 
@@ -318,6 +327,7 @@ static void mlx_poll_cq ( struct net_device *netdev,
318 327
  * @v netdev		Network device
319 328
  */
320 329
 static void mlx_poll ( struct net_device *netdev ) {
330
+	struct mlx_nic *mlx = netdev->priv;
321 331
 	int rc;
322 332
 
323 333
 	if ( ( rc = poll_error_buf() ) != 0 ) {
@@ -330,8 +340,8 @@ static void mlx_poll ( struct net_device *netdev ) {
330 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,7 +396,7 @@ static void mlx_remove ( struct pci_device *pci ) {
386 396
 	struct net_device *netdev = pci_get_drvdata ( pci );
387 397
 
388 398
 	unregister_netdev ( netdev );
389
-	ipoib_close(0);
399
+	ib_driver_close ( 0 );
390 400
 	netdev_nullify ( netdev );
391 401
 	netdev_put ( netdev );
392 402
 }
@@ -473,6 +483,7 @@ static int mlx_probe ( struct pci_device *pci,
473 483
 	struct net_device *netdev;
474 484
 	struct mlx_nic *mlx;
475 485
 	struct ib_mac *mac;
486
+	udqp_t qph;
476 487
 	int rc;
477 488
 
478 489
 	/* Allocate net device */
@@ -489,11 +500,15 @@ static int mlx_probe ( struct pci_device *pci,
489 500
 	adjust_pci_device ( pci );
490 501
 
491 502
 	/* Initialise hardware */
492
-	if ( ( rc = ipoib_init ( pci ) ) != 0 )
503
+	if ( ( rc = ib_driver_init ( pci, &qph ) ) != 0 )
493 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 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 513
 	/* Register network device */
499 514
 	if ( ( rc = register_netdev ( netdev ) ) != 0 )
@@ -503,7 +518,7 @@ static int mlx_probe ( struct pci_device *pci,
503 518
 
504 519
  err_register_netdev:
505 520
  err_ipoib_init:
506
-	ipoib_close(0);
521
+	ib_driver_close ( 0 );
507 522
 	netdev_nullify ( netdev );
508 523
 	netdev_put ( netdev );
509 524
 	return rc;

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

@@ -10,10 +10,6 @@
10 10
 #include <stdint.h>
11 11
 #include <gpxe/netdevice.h>
12 12
 
13
-/** Infiniband hardware address length */
14
-#define IB_ALEN 20
15
-#define IB_HLEN 24
16
-
17 13
 /** An Infiniband Global Identifier */
18 14
 struct ib_gid {
19 15
 	uint8_t bytes[16];
@@ -40,6 +36,9 @@ struct ib_global_route_header {
40 36
 	struct ib_gid dgid;
41 37
 } __attribute__ (( packed ));
42 38
 
39
+/** Infiniband MAC address length */
40
+#define IB_ALEN 20
41
+
43 42
 /** An Infiniband MAC address */
44 43
 struct ib_mac {
45 44
 	/** Queue pair number
@@ -51,15 +50,11 @@ struct ib_mac {
51 50
 	struct ib_gid gid;
52 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 57
 struct ibhdr {
61
-	/** Peer address */
62
-	uint8_t peer[IB_ALEN];
63 58
 	/** Network-layer protocol */
64 59
 	uint16_t proto;
65 60
 	/** Reserved, must be zero */

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

@@ -50,12 +50,12 @@ static int ib_tx ( struct io_buffer *iobuf, struct net_device *netdev,
50 50
 		   struct net_protocol *net_protocol, const void *ll_dest ) {
51 51
 	struct ibhdr *ibhdr = iob_push ( iobuf, sizeof ( *ibhdr ) );
52 52
 
53
-
54 53
 	/* Build Infiniband header */
55
-	memcpy ( ibhdr->peer, ll_dest, IB_ALEN );
56 54
 	ibhdr->proto = net_protocol->net_proto;
57 55
 	ibhdr->reserved = 0;
58 56
 
57
+	( void ) ll_dest;
58
+
59 59
 	/* Hand off to network device */
60 60
 	return netdev_tx ( netdev, iobuf );
61 61
 }
@@ -70,17 +70,6 @@ static int ib_tx ( struct io_buffer *iobuf, struct net_device *netdev,
70 70
  * network-layer protocol.
71 71
  */
72 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 73
 	struct ibhdr *ibhdr = iobuf->data;
85 74
 
86 75
 	/* Sanity check */
@@ -95,7 +84,7 @@ static int ib_rx ( struct io_buffer *iobuf, struct net_device *netdev ) {
95 84
 	iob_pull ( iobuf, sizeof ( *ibhdr ) );
96 85
 
97 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