瀏覽代碼

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

tags/v0.9.3
Michael Brown 18 年之前
父節點
當前提交
8b27da9de1
共有 3 個檔案被更改,包括 98 行新增14 行删除
  1. 36
    5
      src/drivers/net/mlx_ipoib/bit_ops.h
  2. 60
    7
      src/drivers/net/mlx_ipoib/mt25218.c
  3. 2
    2
      src/include/gpxe/infiniband.h

+ 36
- 5
src/drivers/net/mlx_ipoib/bit_ops.h 查看文件

141
 #define MLX_BIT_OFFSET( _structure, _field )				   \
141
 #define MLX_BIT_OFFSET( _structure, _field )				   \
142
 	offsetof ( struct _structure, _field )
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
 /** Bit width of a field within a pseudo_bit_t structure */
156
 /** Bit width of a field within a pseudo_bit_t structure */
145
 #define MLX_BIT_WIDTH( _structure, _field )				   \
157
 #define MLX_BIT_WIDTH( _structure, _field )				   \
146
 	sizeof ( ( ( struct _structure * ) NULL )->_field )
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
  * Assemble native-endian dword from named fields and values
165
  * Assemble native-endian dword from named fields and values
150
  *
166
  *
151
  */
167
  */
152
 
168
 
153
 #define MLX_ASSEMBLE_1( _structure, _index, _field, _value )		   \
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
 #define MLX_ASSEMBLE_2( _structure, _index, _field, _value, ... )	   \
172
 #define MLX_ASSEMBLE_2( _structure, _index, _field, _value, ... )	   \
158
 	( MLX_ASSEMBLE_1 ( _structure, _index, _field, _value ) |	   \
173
 	( MLX_ASSEMBLE_1 ( _structure, _index, _field, _value ) |	   \
172
  */
187
  */
173
 
188
 
174
 #define MLX_MASK_1( _structure, _index, _field )			   \
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
 #define MLX_MASK_2( _structure, _index, _field, ... )			   \
193
 #define MLX_MASK_2( _structure, _index, _field, ... )			   \
180
 	( MLX_MASK_1 ( _structure, _index, _field ) |			   \
194
 	( MLX_MASK_1 ( _structure, _index, _field ) |			   \
231
 		*__ptr = cpu_to_be32 ( __value );			   \
245
 		*__ptr = cpu_to_be32 ( __value );			   \
232
 	} while ( 0 )
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
 #endif				/* __bit_ops_h__ */
265
 #endif				/* __bit_ops_h__ */

+ 60
- 7
src/drivers/net/mlx_ipoib/mt25218.c 查看文件

27
 	/** Doorbell number */
27
 	/** Doorbell number */
28
 	unsigned int doorbell_idx;
28
 	unsigned int doorbell_idx;
29
 	/** Work queue entries */
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
 struct arbel {
34
 struct arbel {
34
 	/** User Access Region */
35
 	/** User Access Region */
35
-	unsigned long uar;
36
+	void *uar;
36
 	/** Doorbell records */
37
 	/** Doorbell records */
37
 	union db_record_st *db_rec;
38
 	union db_record_st *db_rec;
38
 };
39
 };
88
 static int mlx_transmit ( struct net_device *netdev,
89
 static int mlx_transmit ( struct net_device *netdev,
89
 			  struct io_buffer *iobuf ) {
90
 			  struct io_buffer *iobuf ) {
90
 	struct mlx_nic *mlx = netdev->priv;
91
 	struct mlx_nic *mlx = netdev->priv;
91
-	ud_av_t av = iobuf->data;
92
 	ud_send_wqe_t snd_wqe;
92
 	ud_send_wqe_t snd_wqe;
93
 	int rc;
93
 	int rc;
94
 
94
 
110
 	return 0;
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
  * Handle TX completion
166
  * Handle TX completion
115
  *
167
  *
234
 static struct net_device_operations mlx_operations = {
286
 static struct net_device_operations mlx_operations = {
235
 	.open		= mlx_open,
287
 	.open		= mlx_open,
236
 	.close		= mlx_close,
288
 	.close		= mlx_close,
237
-	.transmit	= mlx_transmit,
289
+	.transmit	= mlx_transmit_direct,
238
 	.poll		= mlx_poll,
290
 	.poll		= mlx_poll,
239
 	.irq		= mlx_irq,
291
 	.irq		= mlx_irq,
240
 };
292
 };
274
 	/* Allocate work queue entry */
326
 	/* Allocate work queue entry */
275
 	prev_wqe_idx = wq->posted;
327
 	prev_wqe_idx = wq->posted;
276
 	wqe_idx = ( prev_wqe_idx + 1 );
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
 		DBGC ( arbel, "ARBEL %p send queue full", arbel );
330
 		DBGC ( arbel, "ARBEL %p send queue full", arbel );
279
 		return -ENOBUFS;
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
 	/* Construct work queue entry */
337
 	/* Construct work queue entry */
285
 	memset ( &wqe->next.control, 0,
338
 	memset ( &wqe->next.control, 0,

+ 2
- 2
src/include/gpxe/infiniband.h 查看文件

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

Loading…
取消
儲存