Browse Source

Gets a response out of the hardware. (An error completion, to be precise.)

tags/v0.9.3
Michael Brown 16 years ago
parent
commit
8b27da9de1

+ 36
- 5
src/drivers/net/mlx_ipoib/bit_ops.h View File

@@ -141,18 +141,33 @@ struct addr_64_st {
141 141
 #define MLX_BIT_OFFSET( _structure, _field )				   \
142 142
 	offsetof ( struct _structure, _field )
143 143
 
144
+/** Dword offset of a field within a pseudo_bit_t structure */
145
+#define MLX_DWORD_OFFSET( _structure, _field )				   \
146
+	( MLX_BIT_OFFSET ( _structure, _field ) / 32 )
147
+
148
+/** Dword bit offset of a field within a pseudo_bit_t structure
149
+ *
150
+ * Yes, using mod-32 would work, but would lose the check for the
151
+ * error of specifying a mismatched field name and dword index.
152
+ */
153
+#define MLX_DWORD_BIT_OFFSET( _structure, _index, _field )		   \
154
+	( MLX_BIT_OFFSET ( _structure, _field ) - ( 32 * (_index) ) )
155
+
144 156
 /** Bit width of a field within a pseudo_bit_t structure */
145 157
 #define MLX_BIT_WIDTH( _structure, _field )				   \
146 158
 	sizeof ( ( ( struct _structure * ) NULL )->_field )
147 159
 
160
+/** Bit mask for a field within a pseudo_bit_t structure */
161
+#define MLX_BIT_MASK( _structure, _field )				   \
162
+	( ( 1 << MLX_BIT_WIDTH ( _structure, _field ) ) - 1 )
163
+
148 164
 /*
149 165
  * Assemble native-endian dword from named fields and values
150 166
  *
151 167
  */
152 168
 
153 169
 #define MLX_ASSEMBLE_1( _structure, _index, _field, _value )		   \
154
-	( (_value) <<							   \
155
-	  ( MLX_BIT_OFFSET ( _structure, _field ) - ( 32 * (_index) ) ) )
170
+	( (_value) << MLX_DWORD_BIT_OFFSET ( _structure, _index, _field ) )
156 171
 
157 172
 #define MLX_ASSEMBLE_2( _structure, _index, _field, _value, ... )	   \
158 173
 	( MLX_ASSEMBLE_1 ( _structure, _index, _field, _value ) |	   \
@@ -172,9 +187,8 @@ struct addr_64_st {
172 187
  */
173 188
 
174 189
 #define MLX_MASK_1( _structure, _index, _field )			   \
175
-	MLX_ASSEMBLE_1 ( _structure, _index, _field,			   \
176
-			 ( ( 1 << MLX_BIT_WIDTH ( _structure,		   \
177
-						  _field ) ) - 1 ) )
190
+	( MLX_BIT_MASK ( _structure, _field ) <<			   \
191
+	  MLX_DWORD_BIT_OFFSET ( _structure, _index, _field ) )
178 192
 
179 193
 #define MLX_MASK_2( _structure, _index, _field, ... )			   \
180 194
 	( MLX_MASK_1 ( _structure, _index, _field ) |			   \
@@ -231,4 +245,21 @@ struct addr_64_st {
231 245
 		*__ptr = cpu_to_be32 ( __value );			   \
232 246
 	} while ( 0 )
233 247
 
248
+/*
249
+ * Extract value of named field
250
+ *
251
+ */
252
+
253
+#define MLX_EXTRACT( _base, _structure, _field )			   \
254
+	( {								   \
255
+		unsigned int __index = 					   \
256
+			MLX_DWORD_OFFSET ( _structure, _field );	   \
257
+		uint32_t *__ptr = ( ( (uint32_t *) (_base) ) + __index );  \
258
+		uint32_t __value = be32_to_cpu ( *__ptr );		   \
259
+		__value >>= MLX_DWORD_BIT_OFFSET ( _structure, __index,	   \
260
+						   _field );		   \
261
+		__value &= MLX_BIT_MASK ( _structure, _field );		   \
262
+		__value;						   \
263
+	} )
264
+
234 265
 #endif				/* __bit_ops_h__ */

+ 60
- 7
src/drivers/net/mlx_ipoib/mt25218.c View File

@@ -27,12 +27,13 @@ struct arbel_send_work_queue {
27 27
 	/** Doorbell number */
28 28
 	unsigned int doorbell_idx;
29 29
 	/** Work queue entries */
30
-	struct ud_send_wqe_st *wqe;
30
+	//	struct ud_send_wqe_st *wqe;
31
+	union ud_send_wqe_u *wqe_u;
31 32
 };
32 33
 
33 34
 struct arbel {
34 35
 	/** User Access Region */
35
-	unsigned long uar;
36
+	void *uar;
36 37
 	/** Doorbell records */
37 38
 	union db_record_st *db_rec;
38 39
 };
@@ -88,7 +89,6 @@ static uint8_t ib_broadcast[IB_ALEN] = { 0xff, };
88 89
 static int mlx_transmit ( struct net_device *netdev,
89 90
 			  struct io_buffer *iobuf ) {
90 91
 	struct mlx_nic *mlx = netdev->priv;
91
-	ud_av_t av = iobuf->data;
92 92
 	ud_send_wqe_t snd_wqe;
93 93
 	int rc;
94 94
 
@@ -110,6 +110,58 @@ static int mlx_transmit ( struct net_device *netdev,
110 110
 	return 0;
111 111
 }
112 112
 
113
+static int arbel_post_send ( struct ib_device *ibdev, struct io_buffer *iobuf,
114
+			     struct ib_address_vector *av,
115
+			     struct ib_queue_pair *qp );
116
+
117
+static struct io_buffer *tx_ring[NUM_IPOIB_SND_WQES];
118
+static int tx_posted = 0;
119
+
120
+static int mlx_transmit_direct ( struct net_device *netdev,
121
+				 struct io_buffer *iobuf ) {
122
+	struct mlx_nic *mlx = netdev->priv;
123
+	int rc;
124
+
125
+	struct arbel arbel = {
126
+		.uar = memfree_pci_dev.uar,
127
+		.db_rec = dev_ib_data.uar_context_base,
128
+	};
129
+	struct arbel_send_work_queue arbel_send_queue = {
130
+		.doorbell_idx = IPOIB_SND_QP_DB_IDX,
131
+		.wqe_u = ( (struct udqp_st *) ipoib_data.ipoib_qph )->snd_wq,
132
+	};
133
+	struct ib_device ibdev = {
134
+		.priv = &arbel,
135
+	};
136
+	struct ib_queue_pair qp = {
137
+		.qpn = ib_get_qpn ( mlx->ipoib_qph ),
138
+		.send = {
139
+			.num_wqes = NUM_IPOIB_SND_WQES,
140
+			.posted = tx_posted,
141
+			.iobufs = tx_ring,
142
+			.priv = &arbel_send_queue,
143
+		},
144
+	};
145
+	struct ud_av_st *bcast_av = mlx->bcast_av;
146
+	struct address_vector_st *bav = &bcast_av->av;
147
+	struct ib_address_vector av = {
148
+		.dest_qp = bcast_av->dest_qp,
149
+		.qkey = bcast_av->qkey,
150
+		.dlid = MLX_EXTRACT ( bav, arbelprm_ud_address_vector_st, rlid ),
151
+		.rate = ( MLX_EXTRACT ( bav, arbelprm_ud_address_vector_st, max_stat_rate ) ? 1 : 4 ),
152
+		.sl = MLX_EXTRACT ( bav, arbelprm_ud_address_vector_st, sl ),
153
+		.gid_present = 1,
154
+	};
155
+	memcpy ( &av.gid, ( ( void * ) bav ) + 16, 16 );
156
+
157
+	rc = arbel_post_send ( &ibdev, iobuf, &av, &qp );
158
+
159
+	tx_posted = qp.send.posted;
160
+
161
+	return rc;
162
+}
163
+
164
+
113 165
 /**
114 166
  * Handle TX completion
115 167
  *
@@ -234,7 +286,7 @@ static void mlx_irq ( struct net_device *netdev, int enable ) {
234 286
 static struct net_device_operations mlx_operations = {
235 287
 	.open		= mlx_open,
236 288
 	.close		= mlx_close,
237
-	.transmit	= mlx_transmit,
289
+	.transmit	= mlx_transmit_direct,
238 290
 	.poll		= mlx_poll,
239 291
 	.irq		= mlx_irq,
240 292
 };
@@ -274,12 +326,13 @@ static int arbel_post_send ( struct ib_device *ibdev, struct io_buffer *iobuf,
274 326
 	/* Allocate work queue entry */
275 327
 	prev_wqe_idx = wq->posted;
276 328
 	wqe_idx = ( prev_wqe_idx + 1 );
277
-	if ( wq->iobuf[wqe_idx & wqe_idx_mask] ) {
329
+	if ( wq->iobufs[wqe_idx & wqe_idx_mask] ) {
278 330
 		DBGC ( arbel, "ARBEL %p send queue full", arbel );
279 331
 		return -ENOBUFS;
280 332
 	}
281
-	prev_wqe = &arbel_wq->wqe[prev_wqe_idx & wqe_idx_mask];
282
-	wqe = &arbel_wq->wqe[wqe_idx & wqe_idx_mask];
333
+	wq->iobufs[wqe_idx & wqe_idx_mask] = iobuf;
334
+	prev_wqe = &arbel_wq->wqe_u[prev_wqe_idx & wqe_idx_mask].wqe_cont.wqe;
335
+	wqe = &arbel_wq->wqe_u[wqe_idx & wqe_idx_mask].wqe_cont.wqe;
283 336
 
284 337
 	/* Construct work queue entry */
285 338
 	memset ( &wqe->next.control, 0,

+ 2
- 2
src/include/gpxe/infiniband.h View File

@@ -73,10 +73,10 @@ struct ib_work_queue {
73 73
 	 * This is the index of the most recently posted entry.
74 74
 	 */
75 75
 	unsigned int posted;
76
+	/** I/O buffers assigned to work queue */
77
+	struct io_buffer **iobufs;
76 78
 	/** Driver private data */
77 79
 	void *priv;
78
-	/** I/O buffers assigned to work queue */
79
-	struct io_buffer *iobuf[0];
80 80
 };
81 81
 
82 82
 /** An Infiniband Queue Pair */

Loading…
Cancel
Save