Parcourir la source

IPoIB code separated out to ipoib.c.

tags/v0.9.3
Michael Brown il y a 16 ans
Parent
révision
4e78a53cf2

+ 411
- 0
src/drivers/net/ipoib.c Voir le fichier

@@ -0,0 +1,411 @@
1
+/*
2
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <stdint.h>
20
+#include <stdio.h>
21
+#include <string.h>
22
+#include <byteswap.h>
23
+#include <errno.h>
24
+#include <gpxe/if_arp.h>
25
+#include <gpxe/iobuf.h>
26
+#include <gpxe/netdevice.h>
27
+#include <gpxe/infiniband.h>
28
+#include <gpxe/ipoib.h>
29
+
30
+/** @file
31
+ *
32
+ * IP over Infiniband
33
+ */
34
+
35
+
36
+
37
+
38
+
39
+extern unsigned long hack_ipoib_qkey;
40
+extern struct ib_address_vector hack_ipoib_bcast_av;
41
+
42
+
43
+
44
+/** IPoIB MTU */
45
+#define IPOIB_MTU 2048
46
+
47
+/** Number of IPoIB send work queue entries */
48
+#define IPOIB_NUM_SEND_WQES 8
49
+
50
+/** Number of IPoIB receive work queue entries */
51
+#define IPOIB_NUM_RECV_WQES 8
52
+
53
+/** Number of IPoIB completion entries */
54
+#define IPOIB_NUM_CQES 8
55
+
56
+struct ipoib_device {
57
+	struct ib_device *ibdev;
58
+	struct ib_completion_queue *cq;
59
+	struct ib_queue_pair *qp;
60
+	unsigned int rx_fill;
61
+};
62
+
63
+/****************************************************************************
64
+ *
65
+ * IPoIB link layer
66
+ *
67
+ ****************************************************************************
68
+ */
69
+
70
+/** Broadcast IPoIB address */
71
+static struct ipoib_mac ipoib_broadcast = {
72
+	.gid = { { 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
73
+		   0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff } },
74
+};
75
+
76
+/**
77
+ * Transmit IPoIB packet
78
+ *
79
+ * @v iobuf		I/O buffer
80
+ * @v netdev		Network device
81
+ * @v net_protocol	Network-layer protocol
82
+ * @v ll_dest		Link-layer destination address
83
+ *
84
+ * Prepends the IPoIB link-layer header and transmits the packet.
85
+ */
86
+static int ipoib_tx ( struct io_buffer *iobuf, struct net_device *netdev,
87
+		      struct net_protocol *net_protocol,
88
+		      const void *ll_dest ) {
89
+	struct ipoib_hdr *ipoib_hdr =
90
+		iob_push ( iobuf, sizeof ( *ipoib_hdr ) );
91
+
92
+	/* Build IPoIB header */
93
+	memcpy ( &ipoib_hdr->pseudo.peer, ll_dest,
94
+		 sizeof ( ipoib_hdr->pseudo.peer ) );
95
+	ipoib_hdr->real.proto = net_protocol->net_proto;
96
+	ipoib_hdr->real.reserved = 0;
97
+
98
+	/* Hand off to network device */
99
+	return netdev_tx ( netdev, iobuf );
100
+}
101
+
102
+/**
103
+ * Process received IPoIB packet
104
+ *
105
+ * @v iobuf	I/O buffer
106
+ * @v netdev	Network device
107
+ *
108
+ * Strips off the IPoIB link-layer header and passes up to the
109
+ * network-layer protocol.
110
+ */
111
+static int ipoib_rx ( struct io_buffer *iobuf, struct net_device *netdev ) {
112
+	struct ipoib_hdr *ipoib_hdr = iobuf->data;
113
+
114
+	/* Sanity check */
115
+	if ( iob_len ( iobuf ) < sizeof ( *ipoib_hdr ) ) {
116
+		DBG ( "IPoIB packet too short (%d bytes)\n",
117
+		      iob_len ( iobuf ) );
118
+		free_iob ( iobuf );
119
+		return -EINVAL;
120
+	}
121
+
122
+	/* Strip off IPoIB header */
123
+	iob_pull ( iobuf, sizeof ( *ipoib_hdr ) );
124
+
125
+	/* Hand off to network-layer protocol */
126
+	return net_rx ( iobuf, netdev, ipoib_hdr->real.proto,
127
+			&ipoib_hdr->pseudo.peer );
128
+}
129
+
130
+/**
131
+ * Transcribe IPoIB address
132
+ *
133
+ * @v ll_addr	Link-layer address
134
+ * @ret string	Link-layer address in human-readable format
135
+ */
136
+const char * ipoib_ntoa ( const void *ll_addr ) {
137
+	static char buf[61];
138
+	const uint8_t *ipoib_addr = ll_addr;
139
+	unsigned int i;
140
+	char *p = buf;
141
+
142
+	for ( i = 0 ; i < IPOIB_ALEN ; i++ ) {
143
+		p += sprintf ( p, ":%02x", ipoib_addr[i] );
144
+	}
145
+	return ( buf + 1 );
146
+}
147
+
148
+/** IPoIB protocol */
149
+struct ll_protocol ipoib_protocol __ll_protocol = {
150
+	.name		= "IPoIB",
151
+	.ll_proto	= htons ( ARPHRD_INFINIBAND ),
152
+	.ll_addr_len	= IPOIB_ALEN,
153
+	.ll_header_len	= IPOIB_HLEN,
154
+	.ll_broadcast	= ( uint8_t * ) &ipoib_broadcast,
155
+	.tx		= ipoib_tx,
156
+	.rx		= ipoib_rx,
157
+	.ntoa		= ipoib_ntoa,
158
+};
159
+
160
+/****************************************************************************
161
+ *
162
+ * IPoIB network device
163
+ *
164
+ ****************************************************************************
165
+ */
166
+
167
+/**
168
+ * Transmit packet via IPoIB network device
169
+ *
170
+ * @v netdev		Network device
171
+ * @v iobuf		I/O buffer
172
+ * @ret rc		Return status code
173
+ */
174
+static int ipoib_transmit ( struct net_device *netdev,
175
+			    struct io_buffer *iobuf ) {
176
+	struct ipoib_device *ipoib = netdev->priv;
177
+	struct ib_device *ibdev = ipoib->ibdev;
178
+	struct ipoib_pseudo_hdr *ipoib_pshdr = iobuf->data;
179
+
180
+	if ( iob_len ( iobuf ) < sizeof ( *ipoib_pshdr ) ) {
181
+		DBGC ( ipoib, "IPoIB %p buffer too short\n", ipoib );
182
+		return -EINVAL;
183
+	}
184
+
185
+	iob_pull ( iobuf, ( sizeof ( *ipoib_pshdr ) ) );
186
+	return ib_post_send ( ibdev, ipoib->qp,
187
+			      &hack_ipoib_bcast_av, iobuf );
188
+}
189
+
190
+/**
191
+ * Handle IPoIB send completion
192
+ *
193
+ * @v ibdev		Infiniband device
194
+ * @v qp		Queue pair
195
+ * @v completion	Completion
196
+ * @v iobuf		I/O buffer
197
+ */
198
+static void ipoib_complete_send ( struct ib_device *ibdev __unused,
199
+				  struct ib_queue_pair *qp,
200
+				  struct ib_completion *completion,
201
+				  struct io_buffer *iobuf ) {
202
+	struct net_device *netdev = qp->owner_priv;
203
+
204
+	netdev_tx_complete_err ( netdev, iobuf,
205
+				 ( completion->syndrome ? -EIO : 0 ) );
206
+}
207
+
208
+/**
209
+ * Handle IPoIB receive completion
210
+ *
211
+ * @v ibdev		Infiniband device
212
+ * @v qp		Queue pair
213
+ * @v completion	Completion
214
+ * @v iobuf		I/O buffer
215
+ */
216
+static void ipoib_complete_recv ( struct ib_device *ibdev __unused,
217
+				  struct ib_queue_pair *qp,
218
+				  struct ib_completion *completion,
219
+				  struct io_buffer *iobuf ) {
220
+	struct net_device *netdev = qp->owner_priv;
221
+	struct ipoib_device *ipoib = netdev->priv;
222
+	struct ib_global_route_header *grh = iobuf->data;
223
+	struct ipoib_pseudo_hdr *ipoib_pshdr;
224
+
225
+	if ( completion->syndrome ) {
226
+		netdev_rx_err ( netdev, iobuf, -EIO );
227
+	} else {
228
+		iob_put ( iobuf, completion->len );
229
+		iob_pull ( iobuf, ( sizeof ( *grh ) -
230
+				    sizeof ( *ipoib_pshdr ) ) );
231
+		/* FIXME: fill in a MAC address for the sake of AoE! */
232
+		netdev_rx ( netdev, iobuf );
233
+	}
234
+
235
+	ipoib->rx_fill--;
236
+}
237
+
238
+/**
239
+ * Refill IPoIB receive ring
240
+ *
241
+ * @v ipoib		IPoIB device
242
+ */
243
+static void ipoib_refill_recv ( struct ipoib_device *ipoib ) {
244
+	struct ib_device *ibdev = ipoib->ibdev;
245
+	struct io_buffer *iobuf;
246
+	int rc;
247
+
248
+	while ( ipoib->rx_fill < IPOIB_NUM_RECV_WQES ) {
249
+		iobuf = alloc_iob ( IPOIB_MTU );
250
+		if ( ! iobuf )
251
+			break;
252
+		if ( ( rc = ib_post_recv ( ibdev, ipoib->qp,
253
+					   iobuf ) ) != 0 ) {
254
+			free_iob ( iobuf );
255
+			break;
256
+		}
257
+		ipoib->rx_fill++;
258
+	}
259
+}
260
+
261
+/**
262
+ * Poll IPoIB network device
263
+ *
264
+ * @v netdev		Network device
265
+ */
266
+static void ipoib_poll ( struct net_device *netdev ) {
267
+	struct ipoib_device *ipoib = netdev->priv;
268
+	struct ib_device *ibdev = ipoib->ibdev;
269
+
270
+	ib_poll_cq ( ibdev, ipoib->cq, ipoib_complete_send,
271
+		     ipoib_complete_recv );
272
+	ipoib_refill_recv ( ipoib );
273
+}
274
+
275
+/**
276
+ * Enable/disable interrupts on IPoIB network device
277
+ *
278
+ * @v netdev		Network device
279
+ * @v enable		Interrupts should be enabled
280
+ */
281
+static void ipoib_irq ( struct net_device *netdev __unused,
282
+			int enable __unused ) {
283
+	/* No implementation */
284
+}
285
+
286
+/**
287
+ * Open IPoIB network device
288
+ *
289
+ * @v netdev		Network device
290
+ * @ret rc		Return status code
291
+ */
292
+static int ipoib_open ( struct net_device *netdev ) {
293
+	struct ipoib_device *ipoib = netdev->priv;
294
+	struct ib_device *ibdev = ipoib->ibdev;
295
+	int rc;
296
+
297
+	/* Attach to broadcast multicast GID */
298
+	if ( ( rc = ib_mcast_attach ( ibdev, ipoib->qp,
299
+				      &ibdev->broadcast_gid ) ) != 0 ) {
300
+		DBG ( "Could not attach to broadcast GID: %s\n",
301
+		      strerror ( rc ) );
302
+		return rc;
303
+	}
304
+
305
+	/* Fill receive ring */
306
+	ipoib_refill_recv ( ipoib );
307
+
308
+	return 0;
309
+}
310
+
311
+/**
312
+ * Close IPoIB network device
313
+ *
314
+ * @v netdev		Network device
315
+ */
316
+static void ipoib_close ( struct net_device *netdev ) {
317
+	struct ipoib_device *ipoib = netdev->priv;
318
+	struct ib_device *ibdev = ipoib->ibdev;
319
+
320
+	/* Detach from broadcast multicast GID */
321
+	ib_mcast_detach ( ibdev, ipoib->qp, &ipoib_broadcast.gid );
322
+
323
+	/* FIXME: should probably flush the receive ring */
324
+}
325
+
326
+/** IPoIB network device operations */
327
+static struct net_device_operations ipoib_operations = {
328
+	.open		= ipoib_open,
329
+	.close		= ipoib_close,
330
+	.transmit	= ipoib_transmit,
331
+	.poll		= ipoib_poll,
332
+	.irq		= ipoib_irq,
333
+};
334
+
335
+/**
336
+ * Probe IPoIB device
337
+ *
338
+ * @v ibdev		Infiniband device
339
+ * @ret rc		Return status code
340
+ */
341
+int ipoib_probe ( struct ib_device *ibdev ) {
342
+	struct net_device *netdev;
343
+	struct ipoib_device *ipoib;
344
+	struct ipoib_mac *mac;
345
+	int rc;
346
+
347
+	/* Allocate network device */
348
+	netdev = alloc_ipoibdev ( sizeof ( *ipoib ) );
349
+	if ( ! netdev )
350
+		return -ENOMEM;
351
+	netdev_init ( netdev, &ipoib_operations );
352
+	ipoib = netdev->priv;
353
+	ib_set_ownerdata ( ibdev, netdev );
354
+	netdev->dev = ibdev->dev;
355
+	memset ( ipoib, 0, sizeof ( *ipoib ) );
356
+	ipoib->ibdev = ibdev;
357
+
358
+	/* Allocate completion queue */
359
+	ipoib->cq = ib_create_cq ( ibdev, IPOIB_NUM_CQES );
360
+	if ( ! ipoib->cq ) {
361
+		DBGC ( ipoib, "IPoIB %p could not allocate completion queue\n",
362
+		       ipoib );
363
+		rc = -ENOMEM;
364
+		goto err_create_cq;
365
+	}
366
+
367
+	/* Allocate queue pair */
368
+	ipoib->qp = ib_create_qp ( ibdev, IPOIB_NUM_SEND_WQES,
369
+				   ipoib->cq, IPOIB_NUM_RECV_WQES,
370
+				   ipoib->cq, hack_ipoib_qkey );
371
+	if ( ! ipoib->qp ) {
372
+		DBGC ( ipoib, "IPoIB %p could not allocate queue pair\n",
373
+		       ipoib );
374
+		rc = -ENOMEM;
375
+		goto err_create_qp;
376
+	}
377
+	ipoib->qp->owner_priv = netdev;
378
+
379
+	/* Construct MAC address */
380
+	mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
381
+	mac->qpn = htonl ( ipoib->qp->qpn );
382
+	memcpy ( &mac->gid, &ibdev->port_gid, sizeof ( mac->gid ) );
383
+
384
+	/* Register network device */
385
+	if ( ( rc = register_netdev ( netdev ) ) != 0 )
386
+		goto err_register_netdev;
387
+
388
+	return 0;
389
+
390
+ err_register_netdev:
391
+	ib_destroy_qp ( ibdev, ipoib->qp );
392
+ err_create_qp:
393
+	ib_destroy_cq ( ibdev, ipoib->cq );
394
+ err_create_cq:
395
+	netdev_nullify ( netdev );
396
+	netdev_put ( netdev );
397
+	return rc;
398
+}
399
+
400
+/**
401
+ * Remove IPoIB device
402
+ *
403
+ * @v ibdev		Infiniband device
404
+ */
405
+void ipoib_remove ( struct ib_device *ibdev ) {
406
+	struct net_device *netdev = ib_get_ownerdata ( ibdev );
407
+
408
+	unregister_netdev ( netdev );
409
+	netdev_nullify ( netdev );
410
+	netdev_put ( netdev );
411
+}

+ 3
- 2
src/drivers/net/mlx_ipoib/ib_driver.c Voir le fichier

@@ -63,6 +63,7 @@ static int wait_logic_link_up(__u8 port)
63 63
 }
64 64
 
65 65
 unsigned long ipoib_qkey;
66
+unsigned long hack_ipoib_qkey;
66 67
 
67 68
 static int ib_driver_init(struct pci_device *pci, udqp_t * ipoib_qph_p)
68 69
 {
@@ -149,7 +150,7 @@ static int ib_driver_init(struct pci_device *pci, udqp_t * ipoib_qph_p)
149 150
 			qkey, mlid);
150 151
 	}
151 152
 
152
-	ipoib_qkey = qkey;
153
+	hack_ipoib_qkey = ipoib_qkey = qkey;
153 154
 
154 155
 #if 0
155 156
 	rc = create_ipoib_qp(&ib_data.ipoib_qp,
@@ -285,7 +286,7 @@ static int poll_cqe_tout(cq_t cqh, __u16 tout, void **wqe, int *good_p)
285 286
 
286 287
 	end = currticks() + tout;
287 288
 	do {
288
-		rc = ib_poll_cq(cqh, &ib_cqe, &num_cqes);
289
+		rc = ib_poll_cqx(cqh, &ib_cqe, &num_cqes);
289 290
 		if (rc)
290 291
 			return rc;
291 292
 

+ 1
- 1
src/drivers/net/mlx_ipoib/ib_driver.h Voir le fichier

@@ -153,7 +153,7 @@ static int gw_read_cr(__u32 addr, __u32 * result);
153 153
 static int gw_write_cr(__u32 addr, __u32 data);
154 154
 static ud_av_t alloc_ud_av(void);
155 155
 static void free_ud_av(ud_av_t av);
156
-static int ib_poll_cq(cq_t cq, struct ib_cqe_st *ib_cqe_p, __u8 * num_cqes);
156
+static int ib_poll_cqx(cq_t cq, struct ib_cqe_st *ib_cqe_p, __u8 * num_cqes);
157 157
 static int add_qp_to_mcast_group(union ib_gid_u mcast_gid, __u8 add);
158 158
 static int clear_interrupt(void);
159 159
 static int poll_cqe_tout(cq_t cqh, __u16 tout, void **wqe, int *good_p);

+ 1
- 1
src/drivers/net/mlx_ipoib/ib_mt25218.c Voir le fichier

@@ -1730,7 +1730,7 @@ static void dev2ib_cqe(struct ib_cqe_st *ib_cqe_p, union cqe_st *cqe_p)
1730 1730
 		   byte_cnt);
1731 1731
 }
1732 1732
 
1733
-static int ib_poll_cq(void *cqh, struct ib_cqe_st *ib_cqe_p, u8 * num_cqes)
1733
+static int ib_poll_cqx(void *cqh, struct ib_cqe_st *ib_cqe_p, u8 * num_cqes)
1734 1734
 {
1735 1735
 	int rc;
1736 1736
 	union cqe_st cqe;

+ 1
- 1
src/drivers/net/mlx_ipoib/ipoib.c Voir le fichier

@@ -879,7 +879,7 @@ static int ipoib_read_packet(__u16 * prot_p, void *data, unsigned int *size_p,
879 879
 	void *buf, *out_buf;
880 880
 	__u16 prot_type;
881 881
 
882
-	rc = ib_poll_cq(ipoib_data.rcv_cqh, &ib_cqe, &num_cqes);
882
+	rc = ib_poll_cqx(ipoib_data.rcv_cqh, &ib_cqe, &num_cqes);
883 883
 	if (rc) {
884 884
 		return rc;
885 885
 	}

+ 142
- 1
src/drivers/net/mlx_ipoib/mt25218.c Voir le fichier

@@ -16,6 +16,7 @@ Skeleton NIC driver for Etherboot
16 16
 #include <gpxe/iobuf.h>
17 17
 #include <gpxe/netdevice.h>
18 18
 #include <gpxe/infiniband.h>
19
+#include <gpxe/ipoib.h>
19 20
 
20 21
 /* to get some global routines like printf */
21 22
 #include "etherboot.h"
@@ -29,11 +30,18 @@ Skeleton NIC driver for Etherboot
29 30
 #include "arbel.h"
30 31
 
31 32
 
33
+struct ib_address_vector hack_ipoib_bcast_av;
34
+
35
+
36
+
37
+
32 38
 static const struct ib_gid arbel_no_gid = {
33 39
 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }
34 40
 };
35 41
 
36 42
 
43
+#if 0
44
+
37 45
 #define MLX_RX_MAX_FILL NUM_IPOIB_RCV_WQES
38 46
 
39 47
 struct mlx_nic {
@@ -275,6 +283,7 @@ static void mlx_poll ( struct net_device *netdev ) {
275 283
 			&static_ipoib_send_cq,
276 284
 #endif
277 285
 			temp_complete_send, temp_complete_recv );
286
+#if 0
278 287
 	arbel_poll_cq ( &static_ibdev,
279 288
 #if CREATE_OWN
280 289
 			mlx->own_recv_cq,
@@ -282,6 +291,7 @@ static void mlx_poll ( struct net_device *netdev ) {
282 291
 			&static_ipoib_recv_cq,
283 292
 #endif
284 293
 			temp_complete_send, temp_complete_recv );
294
+#endif
285 295
 
286 296
 	mlx_refill_rx ( netdev );
287 297
 }
@@ -308,6 +318,8 @@ static struct net_device_operations mlx_operations = {
308 318
 };
309 319
 
310 320
 
321
+#endif /* 0 */
322
+
311 323
 
312 324
 
313 325
 /***************************************************************************
@@ -1488,6 +1500,8 @@ static int arbel_get_port_gid ( struct arbel *arbel, struct ib_gid *gid ) {
1488 1500
 
1489 1501
 
1490 1502
 
1503
+#if 0
1504
+
1491 1505
 /**
1492 1506
  * Probe PCI device
1493 1507
  *
@@ -1576,14 +1590,17 @@ static int arbel_probe ( struct pci_device *pci,
1576 1590
 		DBG ( "Could not create send CQ\n" );
1577 1591
 		return -EIO;
1578 1592
 	}
1593
+#if 0
1579 1594
 	mlx->own_recv_cq = ib_create_cq ( ibdev, 32 );
1580 1595
 	if ( ! mlx->own_recv_cq ) {
1581 1596
 		DBG ( "Could not create send CQ\n" );
1582 1597
 		return -EIO;
1583 1598
 	}
1599
+#endif
1584 1600
 	mlx->own_qp = ib_create_qp ( ibdev, NUM_IPOIB_SND_WQES,
1585 1601
 				     mlx->own_send_cq, NUM_IPOIB_RCV_WQES,
1586
-				     mlx->own_recv_cq, ipoib_qkey );
1602
+				     //mlx->own_recv_cq, ipoib_qkey );
1603
+				     mlx->own_send_cq, ipoib_qkey );
1587 1604
 	if ( ! mlx->own_qp ) {
1588 1605
 		DBG ( "Could not create QP\n" );
1589 1606
 		return -EIO;
@@ -1621,6 +1638,22 @@ static int arbel_probe ( struct pci_device *pci,
1621 1638
 	}
1622 1639
 #endif
1623 1640
 
1641
+	ibdev->dev = &pci->dev;
1642
+
1643
+
1644
+	struct ud_av_st *bcast_av = mlx->bcast_av;
1645
+	struct arbelprm_ud_address_vector *bav =
1646
+		( struct arbelprm_ud_address_vector * ) &bcast_av->av;
1647
+	struct ib_address_vector *av = &hack_ipoib_bcast_av;
1648
+	av->dest_qp = bcast_av->dest_qp;
1649
+	av->qkey = bcast_av->qkey;
1650
+	av->dlid = MLX_GET ( bav, rlid );
1651
+	av->rate = ( MLX_GET ( bav, max_stat_rate ) ? 1 : 4 );
1652
+	av->sl = MLX_GET ( bav, sl );
1653
+	av->gid_present = 1;
1654
+	memcpy ( &av->gid, ( ( void * ) bav ) + 16, 16 );
1655
+
1656
+
1624 1657
 	/* Register network device */
1625 1658
 	if ( ( rc = register_netdev ( netdev ) ) != 0 )
1626 1659
 		goto err_register_netdev;
@@ -1650,6 +1683,114 @@ static void arbel_remove ( struct pci_device *pci ) {
1650 1683
 	netdev_put ( netdev );
1651 1684
 }
1652 1685
 
1686
+#endif /* 0 */
1687
+
1688
+
1689
+
1690
+/**
1691
+ * Probe PCI device
1692
+ *
1693
+ * @v pci		PCI device
1694
+ * @v id		PCI ID
1695
+ * @ret rc		Return status code
1696
+ */
1697
+static int arbel_probe ( struct pci_device *pci,
1698
+			 const struct pci_device_id *id __unused ) {
1699
+	struct ib_device *ibdev;
1700
+	struct arbelprm_query_dev_lim dev_lim;
1701
+	struct arbel *arbel;
1702
+	udqp_t qph;
1703
+	int rc;
1704
+
1705
+	/* Allocate Infiniband device */
1706
+	ibdev = alloc_ibdev ( sizeof ( *arbel ) );
1707
+	if ( ! ibdev )
1708
+		return -ENOMEM;
1709
+	ibdev->op = &arbel_ib_operations;
1710
+	pci_set_drvdata ( pci, ibdev );
1711
+	ibdev->dev = &pci->dev;
1712
+	arbel = ibdev->dev_priv;
1713
+	memset ( arbel, 0, sizeof ( *arbel ) );
1714
+
1715
+	/* Fix up PCI device */
1716
+	adjust_pci_device ( pci );
1717
+
1718
+	/* Initialise hardware */
1719
+	if ( ( rc = ib_driver_init ( pci, &qph ) ) != 0 )
1720
+		goto err_ib_driver_init;
1721
+
1722
+	/* Hack up IB structures */
1723
+	arbel->config = memfree_pci_dev.cr_space;
1724
+	arbel->mailbox_in = dev_buffers_p->inprm_buf;
1725
+	arbel->mailbox_out = dev_buffers_p->outprm_buf;
1726
+	arbel->uar = memfree_pci_dev.uar;
1727
+	arbel->db_rec = dev_ib_data.uar_context_base;
1728
+	arbel->reserved_lkey = dev_ib_data.mkey;
1729
+	arbel->eqn = dev_ib_data.eq.eqn;
1730
+
1731
+	/* Get device limits */
1732
+	if ( ( rc = arbel_cmd_query_dev_lim ( arbel, &dev_lim ) ) != 0 ) {
1733
+		DBGC ( arbel, "Arbel %p could not get device limits: %s\n",
1734
+		       arbel, strerror ( rc ) );
1735
+		goto err_query_dev_lim;
1736
+	}
1737
+	arbel->limits.reserved_uars = MLX_GET ( &dev_lim, num_rsvd_uars );
1738
+	arbel->limits.reserved_cqs =
1739
+		( 1 << MLX_GET ( &dev_lim, log2_rsvd_cqs ) );
1740
+	arbel->limits.reserved_qps =
1741
+		( 1 << MLX_GET ( &dev_lim, log2_rsvd_qps ) );
1742
+
1743
+	/* Get port GID */
1744
+	if ( ( rc = arbel_get_port_gid ( arbel, &ibdev->port_gid ) ) != 0 ) {
1745
+		DBGC ( arbel, "Arbel %p could not determine port GID: %s\n",
1746
+		       arbel, strerror ( rc ) );
1747
+		goto err_get_port_gid;
1748
+	}
1749
+
1750
+	struct ud_av_st *bcast_av = ib_data.bcast_av;
1751
+	struct arbelprm_ud_address_vector *bav =
1752
+		( struct arbelprm_ud_address_vector * ) &bcast_av->av;
1753
+	struct ib_address_vector *av = &hack_ipoib_bcast_av;
1754
+	av->dest_qp = bcast_av->dest_qp;
1755
+	av->qkey = bcast_av->qkey;
1756
+	av->dlid = MLX_GET ( bav, rlid );
1757
+	av->rate = ( MLX_GET ( bav, max_stat_rate ) ? 1 : 4 );
1758
+	av->sl = MLX_GET ( bav, sl );
1759
+	av->gid_present = 1;
1760
+	memcpy ( &av->gid, ( ( void * ) bav ) + 16, 16 );
1761
+
1762
+	memcpy ( &ibdev->broadcast_gid, &ib_data.bcast_gid, 16 );
1763
+
1764
+	/* Add IPoIB device */
1765
+	if ( ( rc = ipoib_probe ( ibdev ) ) != 0 ) {
1766
+		DBGC ( arbel, "Arbel %p could not add IPoIB device: %s\n",
1767
+		       arbel, strerror ( rc ) );
1768
+		goto err_ipoib_probe;
1769
+	}
1770
+
1771
+	return 0;
1772
+
1773
+ err_ipoib_probe:
1774
+ err_get_port_gid:
1775
+ err_query_dev_lim:
1776
+	ib_driver_close ( 0 );
1777
+ err_ib_driver_init:
1778
+	free_ibdev ( ibdev );
1779
+	return rc;
1780
+}
1781
+
1782
+/**
1783
+ * Remove PCI device
1784
+ *
1785
+ * @v pci		PCI device
1786
+ */
1787
+static void arbel_remove ( struct pci_device *pci ) {
1788
+	struct ib_device *ibdev = pci_get_drvdata ( pci );
1789
+
1790
+	ipoib_remove ( ibdev );
1791
+	ib_driver_close ( 0 );
1792
+}
1793
+
1653 1794
 static struct pci_device_id arbel_nics[] = {
1654 1795
 	PCI_ROM ( 0x15b3, 0x6282, "MT25218", "MT25218 HCA driver" ),
1655 1796
 	PCI_ROM ( 0x15b3, 0x6274, "MT25204", "MT25204 HCA driver" ),

+ 2
- 0
src/include/gpxe/errfile.h Voir le fichier

@@ -101,6 +101,8 @@
101 101
 #define ERRFILE_via_rhine	     ( ERRFILE_DRIVER | 0x00440000 )
102 102
 #define ERRFILE_via_velocity	     ( ERRFILE_DRIVER | 0x00450000 )
103 103
 #define ERRFILE_w89c840		     ( ERRFILE_DRIVER | 0x00460000 )
104
+#define ERRFILE_ipoib		     ( ERRFILE_DRIVER | 0x00470000 )
105
+#define ERRFILE_mt25218		     ( ERRFILE_DRIVER | 0x00480000 )
104 106
 
105 107
 #define ERRFILE_scsi		     ( ERRFILE_DRIVER | 0x00700000 )
106 108
 

+ 114
- 35
src/include/gpxe/infiniband.h Voir le fichier

@@ -8,34 +8,11 @@
8 8
  */
9 9
 
10 10
 #include <stdint.h>
11
-#include <gpxe/netdevice.h>
11
+#include <gpxe/device.h>
12 12
 
13
-/** An Infiniband Global Identifier */
14
-struct ib_gid {
15
-	uint8_t bytes[16];
16
-};
17 13
 
18
-/** An Infiniband Global Route Header */
19
-struct ib_global_route_header {
20
-	/** IP version, traffic class, and flow label
21
-	 *
22
-	 *  4 bits : Version of the GRH
23
-	 *  8 bits : Traffic class
24
-	 * 20 bits : Flow label
25
-	 */
26
-	uint32_t ipver_tclass_flowlabel;
27
-	/** Payload length */
28
-	uint16_t paylen;
29
-	/** Next header */
30
-	uint8_t nxthdr;
31
-	/** Hop limit */
32
-	uint8_t hoplmt;
33
-	/** Source GID */
34
-	struct ib_gid sgid;
35
-	/** Destiniation GID */
36
-	struct ib_gid dgid;
37
-} __attribute__ (( packed ));
38 14
 
15
+#if 0
39 16
 /** Infiniband MAC address length */
40 17
 #define IB_ALEN 20
41 18
 
@@ -60,9 +37,41 @@ struct ibhdr {
60 37
 	/** Reserved, must be zero */
61 38
 	uint16_t reserved;
62 39
 } __attribute__ (( packed ));
40
+#endif
41
+
63 42
 
64 43
 
65 44
 
45
+
46
+
47
+
48
+
49
+/** An Infiniband Global Identifier */
50
+struct ib_gid {
51
+	uint8_t bytes[16];
52
+};
53
+
54
+/** An Infiniband Global Route Header */
55
+struct ib_global_route_header {
56
+	/** IP version, traffic class, and flow label
57
+	 *
58
+	 *  4 bits : Version of the GRH
59
+	 *  8 bits : Traffic class
60
+	 * 20 bits : Flow label
61
+	 */
62
+	uint32_t ipver_tclass_flowlabel;
63
+	/** Payload length */
64
+	uint16_t paylen;
65
+	/** Next header */
66
+	uint8_t nxthdr;
67
+	/** Hop limit */
68
+	uint8_t hoplmt;
69
+	/** Source GID */
70
+	struct ib_gid sgid;
71
+	/** Destiniation GID */
72
+	struct ib_gid dgid;
73
+} __attribute__ (( packed ));
74
+
66 75
 struct ib_device;
67 76
 struct ib_queue_pair;
68 77
 struct ib_completion_queue;
@@ -223,8 +232,7 @@ struct ib_device_operations {
223 232
 			      struct ib_queue_pair *qp,
224 233
 			      struct ib_address_vector *av,
225 234
 			      struct io_buffer *iobuf );
226
-	/**
227
-	 * Post receive work queue entry
235
+	/** Post receive work queue entry
228 236
 	 *
229 237
 	 * @v ibdev		Infiniband device
230 238
 	 * @v qp		Queue pair
@@ -252,8 +260,7 @@ struct ib_device_operations {
252 260
 			     struct ib_completion_queue *cq,
253 261
 			     ib_completer_t complete_send,
254 262
 			     ib_completer_t complete_recv );
255
-	/**
256
-	 * Attach to multicast group
263
+	/** Attach to multicast group
257 264
 	 *
258 265
 	 * @v ibdev		Infiniband device
259 266
 	 * @v qp		Queue pair
@@ -263,8 +270,7 @@ struct ib_device_operations {
263 270
 	int ( * mcast_attach ) ( struct ib_device *ibdev,
264 271
 				 struct ib_queue_pair *qp,
265 272
 				 struct ib_gid *gid );
266
-	/**
267
-	 * Detach from multicast group
273
+	/** Detach from multicast group
268 274
 	 *
269 275
 	 * @v ibdev		Infiniband device
270 276
 	 * @v qp		Queue pair
@@ -276,13 +282,19 @@ struct ib_device_operations {
276 282
 };
277 283
 
278 284
 /** An Infiniband device */
279
-struct ib_device {	
285
+struct ib_device {
280 286
 	/** Port GID */
281 287
 	struct ib_gid port_gid;
288
+	/** Broadcast GID */
289
+	struct ib_gid broadcast_gid;	
290
+	/** Underlying device */
291
+	struct device *dev;
282 292
 	/** Infiniband operations */
283 293
 	struct ib_device_operations *op;
284 294
 	/** Device private data */
285 295
 	void *dev_priv;
296
+	/** Owner private data */
297
+	void *owner_priv;
286 298
 };
287 299
 
288 300
 extern struct ib_completion_queue * ib_create_cq ( struct ib_device *ibdev,
@@ -297,6 +309,52 @@ extern void ib_destroy_qp ( struct ib_device *ibdev,
297 309
 			    struct ib_queue_pair *qp );
298 310
 extern struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
299 311
 					   unsigned long qpn, int is_send );
312
+extern struct ib_device * alloc_ibdev ( size_t priv_size );
313
+extern void free_ibdev ( struct ib_device *ibdev );
314
+
315
+/**
316
+ * Post send work queue entry
317
+ *
318
+ * @v ibdev		Infiniband device
319
+ * @v qp		Queue pair
320
+ * @v av		Address vector
321
+ * @v iobuf		I/O buffer
322
+ * @ret rc		Return status code
323
+ */
324
+static inline __attribute__ (( always_inline )) int
325
+ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
326
+	       struct ib_address_vector *av, struct io_buffer *iobuf ) {
327
+	return ibdev->op->post_send ( ibdev, qp, av, iobuf );
328
+}
329
+
330
+/**
331
+ * Post receive work queue entry
332
+ *
333
+ * @v ibdev		Infiniband device
334
+ * @v qp		Queue pair
335
+ * @v iobuf		I/O buffer
336
+ * @ret rc		Return status code
337
+ */
338
+static inline __attribute__ (( always_inline )) int
339
+ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
340
+	       struct io_buffer *iobuf ) {
341
+	return ibdev->op->post_recv ( ibdev, qp, iobuf );
342
+}
343
+
344
+/**
345
+ * Poll completion queue
346
+ *
347
+ * @v ibdev		Infiniband device
348
+ * @v cq		Completion queue
349
+ * @v complete_send	Send completion handler
350
+ * @v complete_recv	Receive completion handler
351
+ */
352
+static inline __attribute__ (( always_inline )) void
353
+ib_poll_cq ( struct ib_device *ibdev, struct ib_completion_queue *cq,
354
+	     ib_completer_t complete_send, ib_completer_t complete_recv ) {
355
+	ibdev->op->poll_cq ( ibdev, cq, complete_send, complete_recv );
356
+}
357
+
300 358
 
301 359
 /**
302 360
  * Attach to multicast group
@@ -325,6 +383,27 @@ ib_mcast_detach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
325 383
 	ibdev->op->mcast_detach ( ibdev, qp, gid );
326 384
 }
327 385
 
386
+/**
387
+ * Set Infiniband owner-private data
388
+ *
389
+ * @v pci		Infiniband device
390
+ * @v priv		Private data
391
+ */
392
+static inline void ib_set_ownerdata ( struct ib_device *ibdev,
393
+				      void *owner_priv ) {
394
+	ibdev->owner_priv = owner_priv;
395
+}
396
+
397
+/**
398
+ * Get Infiniband owner-private data
399
+ *
400
+ * @v pci		Infiniband device
401
+ * @ret priv		Private data
402
+ */
403
+static inline void * ib_get_ownerdata ( struct ib_device *ibdev ) {
404
+	return ibdev->owner_priv;
405
+}
406
+
328 407
 /*****************************************************************************
329 408
  *
330 409
  * Management datagrams
@@ -435,9 +514,7 @@ union ib_mad {
435 514
 
436 515
 
437 516
 
438
-
439
-
440
-
517
+#if 0
441 518
 
442 519
 extern struct ll_protocol infiniband_protocol;
443 520
 
@@ -459,4 +536,6 @@ static inline struct net_device * alloc_ibdev ( size_t priv_size ) {
459 536
 	return netdev;
460 537
 }
461 538
 
539
+#endif
540
+
462 541
 #endif /* _GPXE_INFINIBAND_H */

+ 78
- 0
src/include/gpxe/ipoib.h Voir le fichier

@@ -0,0 +1,78 @@
1
+#ifndef _GPXE_IPOIB_H
2
+#define _GPXE_IPOIB_H
3
+
4
+/** @file
5
+ *
6
+ * IP over Infiniband
7
+ */
8
+
9
+#include <gpxe/infiniband.h>
10
+
11
+/** IPoIB MAC address length */
12
+#define IPOIB_ALEN 20
13
+
14
+/** An IPoIB MAC address */
15
+struct ipoib_mac {
16
+	/** Queue pair number
17
+	 *
18
+	 * MSB must be zero; QPNs are only 24-bit.
19
+	 */
20
+	uint32_t qpn;
21
+	/** Port GID */
22
+	struct ib_gid gid;
23
+} __attribute__ (( packed ));
24
+
25
+/** IPoIB link-layer header length */
26
+#define IPOIB_HLEN 24
27
+
28
+/**
29
+ * IPoIB link-layer header pseudo portion
30
+ *
31
+ * This part doesn't actually exist on the wire, but it provides a
32
+ * convenient way to fit into the typical network device model.
33
+ */
34
+struct ipoib_pseudo_hdr {
35
+	/** Peer address */
36
+	struct ipoib_mac peer;
37
+} __attribute__ (( packed ));
38
+
39
+/** IPoIB link-layer header real portion */
40
+struct ipoib_real_hdr {
41
+	/** Network-layer protocol */
42
+	uint16_t proto;
43
+	/** Reserved, must be zero */
44
+	uint16_t reserved;
45
+} __attribute__ (( packed ));
46
+
47
+/** An IPoIB link-layer header */
48
+struct ipoib_hdr {
49
+	/** Pseudo portion */
50
+	struct ipoib_pseudo_hdr pseudo;
51
+	/** Real portion */
52
+	struct ipoib_real_hdr real;
53
+} __attribute__ (( packed ));
54
+
55
+extern struct ll_protocol ipoib_protocol;
56
+
57
+extern const char * ipoib_ntoa ( const void *ll_addr );
58
+
59
+/**
60
+ * Allocate IPoIB device
61
+ *
62
+ * @v priv_size		Size of driver private data
63
+ * @ret netdev		Network device, or NULL
64
+ */
65
+static inline struct net_device * alloc_ipoibdev ( size_t priv_size ) {
66
+	struct net_device *netdev;
67
+
68
+	netdev = alloc_netdev ( priv_size );
69
+	if ( netdev ) {
70
+		netdev->ll_protocol = &ipoib_protocol;
71
+	}
72
+	return netdev;
73
+}
74
+
75
+extern int ipoib_probe ( struct ib_device *ibdev );
76
+extern void ipoib_remove ( struct ib_device *ibdev );
77
+
78
+#endif /* _GPXE_IPOIB_H */

+ 30
- 2
src/net/infiniband.c Voir le fichier

@@ -153,8 +153,6 @@ void ib_destroy_qp ( struct ib_device *ibdev,
153 153
 	free ( qp );
154 154
 }
155 155
 
156
-
157
-
158 156
 /**
159 157
  * Find work queue belonging to completion queue
160 158
  *
@@ -174,7 +172,35 @@ struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
174 172
 	return NULL;
175 173
 }
176 174
 
175
+/**
176
+ * Allocate Infiniband device
177
+ *
178
+ * @v priv_size		Size of private data area
179
+ * @ret ibdev		Infiniband device, or NULL
180
+ */
181
+struct ib_device * alloc_ibdev ( size_t priv_size ) {
182
+	struct ib_device *ibdev;
183
+	size_t total_len;
184
+
185
+	total_len = ( sizeof ( *ibdev ) + priv_size );
186
+	ibdev = zalloc ( total_len );
187
+	if ( ibdev ) {
188
+		ibdev->dev_priv = ( ( ( void * ) ibdev ) + sizeof ( *ibdev ) );
189
+	}
190
+	return ibdev;
191
+}
177 192
 
193
+/**
194
+ * Free Infiniband device
195
+ *
196
+ * @v ibdev		Infiniband device
197
+ */
198
+void free_ibdev ( struct ib_device *ibdev ) {
199
+	free ( ibdev );
200
+}
201
+
202
+
203
+#if 0
178 204
 
179 205
 /** Infiniband broadcast MAC address */
180 206
 static uint8_t ib_broadcast[IB_ALEN] = { 0xff, };
@@ -259,3 +285,5 @@ struct ll_protocol infiniband_protocol __ll_protocol = {
259 285
 	.rx		= ib_rx,
260 286
 	.ntoa		= ib_ntoa,
261 287
 };
288
+
289
+#endif

Chargement…
Annuler
Enregistrer