Browse Source

[intelxl] Use one admin queue buffer per admin queue descriptor

We currently use a single data buffer shared between all admin queue
descriptors.  This works for the physical function driver since we
have at most one command in progress and only a single event (which
does not use a data buffer).

The communication path between the physical and virtual function
drivers uses the event data buffer, and there is no way to prevent a
solicited event (i.e. a response to a request) from being overwritten
by an unsolicited event (e.g. a link status change).

Provide individual data buffers for each admin event queue descriptor
(and for each admin command queue descriptor, for the sake of
consistency).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 5 years ago
parent
commit
8f3e648b6c
2 changed files with 197 additions and 118 deletions
  1. 193
    116
      src/drivers/net/intelxl.c
  2. 4
    2
      src/drivers/net/intelxl.h

+ 193
- 116
src/drivers/net/intelxl.c View File

141
  */
141
  */
142
 static int intelxl_create_admin ( struct intelxl_nic *intelxl,
142
 static int intelxl_create_admin ( struct intelxl_nic *intelxl,
143
 				  struct intelxl_admin *admin ) {
143
 				  struct intelxl_admin *admin ) {
144
+	size_t buf_len = ( sizeof ( admin->buf[0] ) * INTELXL_ADMIN_NUM_DESC );
144
 	size_t len = ( sizeof ( admin->desc[0] ) * INTELXL_ADMIN_NUM_DESC );
145
 	size_t len = ( sizeof ( admin->desc[0] ) * INTELXL_ADMIN_NUM_DESC );
145
 	const struct intelxl_admin_offsets *regs = admin->regs;
146
 	const struct intelxl_admin_offsets *regs = admin->regs;
146
 	void *admin_regs = ( intelxl->regs + admin->base );
147
 	void *admin_regs = ( intelxl->regs + admin->base );
147
 	physaddr_t address;
148
 	physaddr_t address;
148
 
149
 
149
 	/* Allocate admin queue */
150
 	/* Allocate admin queue */
150
-	admin->desc = malloc_dma ( ( len + sizeof ( *admin->buffer ) ),
151
-				   INTELXL_ALIGN );
152
-	if ( ! admin->desc )
151
+	admin->buf = malloc_dma ( ( buf_len + len ), INTELXL_ALIGN );
152
+	if ( ! admin->buf )
153
 		return -ENOMEM;
153
 		return -ENOMEM;
154
-	admin->buffer = ( ( ( void * ) admin->desc ) + len );
154
+	admin->desc = ( ( ( void * ) admin->buf ) + buf_len );
155
 
155
 
156
 	/* Initialise admin queue */
156
 	/* Initialise admin queue */
157
 	memset ( admin->desc, 0, len );
157
 	memset ( admin->desc, 0, len );
183
 	       ( ( admin == &intelxl->command ) ? 'T' : 'R' ),
183
 	       ( ( admin == &intelxl->command ) ? 'T' : 'R' ),
184
 	       ( ( unsigned long long ) address ),
184
 	       ( ( unsigned long long ) address ),
185
 	       ( ( unsigned long long ) address + len ),
185
 	       ( ( unsigned long long ) address + len ),
186
-	       ( ( unsigned long long ) virt_to_bus ( admin->buffer ) ),
187
-	       ( ( unsigned long long ) ( virt_to_bus ( admin->buffer ) +
188
-					  sizeof ( admin->buffer[0] ) ) ) );
186
+	       ( ( unsigned long long ) virt_to_bus ( admin->buf ) ),
187
+	       ( ( unsigned long long ) ( virt_to_bus ( admin->buf ) +
188
+					  buf_len ) ) );
189
 	return 0;
189
 	return 0;
190
 }
190
 }
191
 
191
 
197
  */
197
  */
198
 static void intelxl_destroy_admin ( struct intelxl_nic *intelxl,
198
 static void intelxl_destroy_admin ( struct intelxl_nic *intelxl,
199
 				    struct intelxl_admin *admin ) {
199
 				    struct intelxl_admin *admin ) {
200
+	size_t buf_len = ( sizeof ( admin->buf[0] ) * INTELXL_ADMIN_NUM_DESC );
200
 	size_t len = ( sizeof ( admin->desc[0] ) * INTELXL_ADMIN_NUM_DESC );
201
 	size_t len = ( sizeof ( admin->desc[0] ) * INTELXL_ADMIN_NUM_DESC );
201
 	const struct intelxl_admin_offsets *regs = admin->regs;
202
 	const struct intelxl_admin_offsets *regs = admin->regs;
202
 	void *admin_regs = ( intelxl->regs + admin->base );
203
 	void *admin_regs = ( intelxl->regs + admin->base );
205
 	writel ( 0, admin_regs + regs->len );
206
 	writel ( 0, admin_regs + regs->len );
206
 
207
 
207
 	/* Free queue */
208
 	/* Free queue */
208
-	free_dma ( admin->desc, ( len + sizeof ( *admin->buffer ) ) );
209
+	free_dma ( admin->buf, ( buf_len + len ) );
210
+}
211
+
212
+/**
213
+ * Get next admin command queue descriptor
214
+ *
215
+ * @v intelxl		Intel device
216
+ * @ret cmd		Command descriptor
217
+ */
218
+static struct intelxl_admin_descriptor *
219
+intelxl_admin_command_descriptor ( struct intelxl_nic *intelxl ) {
220
+	struct intelxl_admin *admin = &intelxl->command;
221
+	struct intelxl_admin_descriptor *cmd;
222
+
223
+	/* Get and initialise next descriptor */
224
+	cmd = &admin->desc[ admin->index % INTELXL_ADMIN_NUM_DESC ];
225
+	memset ( cmd, 0, sizeof ( *cmd ) );
226
+	return cmd;
227
+}
228
+
229
+/**
230
+ * Get next admin command queue data buffer
231
+ *
232
+ * @v intelxl		Intel device
233
+ * @ret buf		Data buffer
234
+ */
235
+static union intelxl_admin_buffer *
236
+intelxl_admin_command_buffer ( struct intelxl_nic *intelxl ) {
237
+	struct intelxl_admin *admin = &intelxl->command;
238
+	union intelxl_admin_buffer *buf;
239
+
240
+	/* Get next data buffer */
241
+	buf = &admin->buf[ admin->index % INTELXL_ADMIN_NUM_DESC ];
242
+	memset ( buf, 0, sizeof ( *buf ) );
243
+	return buf;
244
+}
245
+
246
+/**
247
+ * Initialise admin event queue descriptor
248
+ *
249
+ * @v intelxl		Intel device
250
+ * @v index		Event queue index
251
+ */
252
+static void intelxl_admin_event_init ( struct intelxl_nic *intelxl,
253
+				       unsigned int index ) {
254
+	struct intelxl_admin *admin = &intelxl->event;
255
+	struct intelxl_admin_descriptor *evt;
256
+	union intelxl_admin_buffer *buf;
257
+	uint64_t address;
258
+
259
+	/* Initialise descriptor */
260
+	evt = &admin->desc[ index % INTELXL_ADMIN_NUM_DESC ];
261
+	buf = &admin->buf[ index % INTELXL_ADMIN_NUM_DESC ];
262
+	address = virt_to_bus ( buf );
263
+	evt->flags = cpu_to_le16 ( INTELXL_ADMIN_FL_BUF );
264
+	evt->len = cpu_to_le16 ( sizeof ( *buf ) );
265
+	evt->params.buffer.high = cpu_to_le32 ( address >> 32 );
266
+	evt->params.buffer.low = cpu_to_le32 ( address & 0xffffffffUL );
209
 }
267
 }
210
 
268
 
211
 /**
269
 /**
212
  * Issue admin queue command
270
  * Issue admin queue command
213
  *
271
  *
214
  * @v intelxl		Intel device
272
  * @v intelxl		Intel device
215
- * @v cmd		Command descriptor
216
  * @ret rc		Return status code
273
  * @ret rc		Return status code
217
  */
274
  */
218
-static int intelxl_admin_command ( struct intelxl_nic *intelxl,
219
-				   struct intelxl_admin_descriptor *cmd ) {
275
+static int intelxl_admin_command ( struct intelxl_nic *intelxl ) {
220
 	struct intelxl_admin *admin = &intelxl->command;
276
 	struct intelxl_admin *admin = &intelxl->command;
221
 	const struct intelxl_admin_offsets *regs = admin->regs;
277
 	const struct intelxl_admin_offsets *regs = admin->regs;
222
 	void *admin_regs = ( intelxl->regs + admin->base );
278
 	void *admin_regs = ( intelxl->regs + admin->base );
223
-	struct intelxl_admin_descriptor *desc;
224
-	uint64_t buffer;
279
+	struct intelxl_admin_descriptor *cmd;
280
+	union intelxl_admin_buffer *buf;
281
+	uint64_t address;
282
+	uint32_t cookie;
225
 	unsigned int index;
283
 	unsigned int index;
226
 	unsigned int tail;
284
 	unsigned int tail;
227
 	unsigned int i;
285
 	unsigned int i;
230
 	/* Get next queue entry */
288
 	/* Get next queue entry */
231
 	index = admin->index++;
289
 	index = admin->index++;
232
 	tail = ( admin->index % INTELXL_ADMIN_NUM_DESC );
290
 	tail = ( admin->index % INTELXL_ADMIN_NUM_DESC );
233
-	desc = &admin->desc[index % INTELXL_ADMIN_NUM_DESC];
234
-
235
-	/* Clear must-be-zero flags */
236
-	cmd->flags &= ~cpu_to_le16 ( INTELXL_ADMIN_FL_DD |
237
-				     INTELXL_ADMIN_FL_CMP |
238
-				     INTELXL_ADMIN_FL_ERR );
239
-
240
-	/* Clear return value */
241
-	cmd->ret = 0;
291
+	cmd = &admin->desc[ index % INTELXL_ADMIN_NUM_DESC ];
292
+	buf = &admin->buf[ index % INTELXL_ADMIN_NUM_DESC ];
293
+	DBGC2 ( intelxl, "INTELXL %p admin command %#x opcode %#04x:\n",
294
+		intelxl, index, le16_to_cpu ( cmd->opcode ) );
242
 
295
 
243
-	/* Populate cookie */
244
-	cmd->cookie = cpu_to_le32 ( index );
296
+	/* Sanity checks */
297
+	assert ( ! ( cmd->flags & cpu_to_le16 ( INTELXL_ADMIN_FL_DD ) ) );
298
+	assert ( ! ( cmd->flags & cpu_to_le16 ( INTELXL_ADMIN_FL_CMP ) ) );
299
+	assert ( ! ( cmd->flags & cpu_to_le16 ( INTELXL_ADMIN_FL_ERR ) ) );
300
+	assert ( cmd->ret == 0 );
245
 
301
 
246
 	/* Populate data buffer address if applicable */
302
 	/* Populate data buffer address if applicable */
247
 	if ( cmd->flags & cpu_to_le16 ( INTELXL_ADMIN_FL_BUF ) ) {
303
 	if ( cmd->flags & cpu_to_le16 ( INTELXL_ADMIN_FL_BUF ) ) {
248
-		buffer = virt_to_bus ( admin->buffer );
249
-		cmd->params.buffer.high = cpu_to_le32 ( buffer >> 32 );
250
-		cmd->params.buffer.low = cpu_to_le32 ( buffer & 0xffffffffUL );
304
+		address = virt_to_bus ( buf );
305
+		cmd->params.buffer.high = cpu_to_le32 ( address >> 32 );
306
+		cmd->params.buffer.low = cpu_to_le32 ( address & 0xffffffffUL );
251
 	}
307
 	}
252
 
308
 
253
-	/* Copy command descriptor to queue entry */
254
-	memcpy ( desc, cmd, sizeof ( *desc ) );
255
-	DBGC2 ( intelxl, "INTELXL %p admin command %#x:\n", intelxl, index );
256
-	DBGC2_HDA ( intelxl, virt_to_phys ( desc ), desc, sizeof ( *desc ) );
309
+	/* Populate cookie */
310
+	cmd->cookie = cpu_to_le32 ( index );
311
+
312
+	/* Record cookie */
313
+	cookie = cmd->cookie;
257
 
314
 
258
 	/* Post command descriptor */
315
 	/* Post command descriptor */
316
+	DBGC2_HDA ( intelxl, virt_to_phys ( cmd ), cmd, sizeof ( *cmd ) );
317
+	if ( cmd->flags & cpu_to_le16 ( INTELXL_ADMIN_FL_BUF ) ) {
318
+		DBGC2_HDA ( intelxl, virt_to_phys ( buf ), buf,
319
+			    le16_to_cpu ( cmd->len ) );
320
+	}
259
 	wmb();
321
 	wmb();
260
 	writel ( tail, admin_regs + regs->tail );
322
 	writel ( tail, admin_regs + regs->tail );
261
 
323
 
263
 	for ( i = 0 ; i < INTELXL_ADMIN_MAX_WAIT_MS ; i++ ) {
325
 	for ( i = 0 ; i < INTELXL_ADMIN_MAX_WAIT_MS ; i++ ) {
264
 
326
 
265
 		/* If response is not complete, delay 1ms and retry */
327
 		/* If response is not complete, delay 1ms and retry */
266
-		if ( ! ( desc->flags & INTELXL_ADMIN_FL_DD ) ) {
328
+		if ( ! ( cmd->flags & INTELXL_ADMIN_FL_DD ) ) {
267
 			mdelay ( 1 );
329
 			mdelay ( 1 );
268
 			continue;
330
 			continue;
269
 		}
331
 		}
270
 		DBGC2 ( intelxl, "INTELXL %p admin command %#x response:\n",
332
 		DBGC2 ( intelxl, "INTELXL %p admin command %#x response:\n",
271
 			intelxl, index );
333
 			intelxl, index );
272
-		DBGC2_HDA ( intelxl, virt_to_phys ( desc ), desc,
273
-			    sizeof ( *desc ) );
334
+		DBGC2_HDA ( intelxl, virt_to_phys ( cmd ), cmd,
335
+			    sizeof ( *cmd ) );
274
 
336
 
275
 		/* Check for cookie mismatch */
337
 		/* Check for cookie mismatch */
276
-		if ( desc->cookie != cmd->cookie ) {
338
+		if ( cmd->cookie != cookie ) {
277
 			DBGC ( intelxl, "INTELXL %p admin command %#x bad "
339
 			DBGC ( intelxl, "INTELXL %p admin command %#x bad "
278
 			       "cookie %#x\n", intelxl, index,
340
 			       "cookie %#x\n", intelxl, index,
279
-			       le32_to_cpu ( desc->cookie ) );
341
+			       le32_to_cpu ( cmd->cookie ) );
280
 			rc = -EPROTO;
342
 			rc = -EPROTO;
281
 			goto err;
343
 			goto err;
282
 		}
344
 		}
283
 
345
 
284
 		/* Check for errors */
346
 		/* Check for errors */
285
-		if ( desc->ret != 0 ) {
347
+		if ( cmd->ret != 0 ) {
286
 			DBGC ( intelxl, "INTELXL %p admin command %#x error "
348
 			DBGC ( intelxl, "INTELXL %p admin command %#x error "
287
 			       "%d\n", intelxl, index,
349
 			       "%d\n", intelxl, index,
288
-			       le16_to_cpu ( desc->ret ) );
350
+			       le16_to_cpu ( cmd->ret ) );
289
 			rc = -EIO;
351
 			rc = -EIO;
290
 			goto err;
352
 			goto err;
291
 		}
353
 		}
292
 
354
 
293
-		/* Copy response back to command descriptor */
294
-		memcpy ( cmd, desc, sizeof ( *cmd ) );
295
-
296
 		/* Success */
355
 		/* Success */
297
 		return 0;
356
 		return 0;
298
 	}
357
 	}
301
 	DBGC ( intelxl, "INTELXL %p timed out waiting for admin command %#x:\n",
360
 	DBGC ( intelxl, "INTELXL %p timed out waiting for admin command %#x:\n",
302
 	       intelxl, index );
361
 	       intelxl, index );
303
  err:
362
  err:
304
-	DBGC_HDA ( intelxl, virt_to_phys ( desc ), cmd, sizeof ( *cmd ) );
305
-	DBGC_HDA ( intelxl, virt_to_phys ( desc ), desc, sizeof ( *desc ) );
363
+	DBGC_HDA ( intelxl, virt_to_phys ( cmd ), cmd, sizeof ( *cmd ) );
306
 	return rc;
364
 	return rc;
307
 }
365
 }
308
 
366
 
313
  * @ret rc		Return status code
371
  * @ret rc		Return status code
314
  */
372
  */
315
 static int intelxl_admin_version ( struct intelxl_nic *intelxl ) {
373
 static int intelxl_admin_version ( struct intelxl_nic *intelxl ) {
316
-	struct intelxl_admin_descriptor cmd;
317
-	struct intelxl_admin_version_params *version = &cmd.params.version;
374
+	struct intelxl_admin_descriptor *cmd;
375
+	struct intelxl_admin_version_params *version;
318
 	unsigned int api;
376
 	unsigned int api;
319
 	int rc;
377
 	int rc;
320
 
378
 
321
 	/* Populate descriptor */
379
 	/* Populate descriptor */
322
-	memset ( &cmd, 0, sizeof ( cmd ) );
323
-	cmd.opcode = cpu_to_le16 ( INTELXL_ADMIN_VERSION );
380
+	cmd = intelxl_admin_command_descriptor ( intelxl );
381
+	cmd->opcode = cpu_to_le16 ( INTELXL_ADMIN_VERSION );
382
+	version = &cmd->params.version;
324
 
383
 
325
 	/* Issue command */
384
 	/* Issue command */
326
-	if ( ( rc = intelxl_admin_command ( intelxl, &cmd ) ) != 0 )
385
+	if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
327
 		return rc;
386
 		return rc;
328
 	api = le16_to_cpu ( version->api.major );
387
 	api = le16_to_cpu ( version->api.major );
329
 	DBGC ( intelxl, "INTELXL %p firmware v%d.%d API v%d.%d\n",
388
 	DBGC ( intelxl, "INTELXL %p firmware v%d.%d API v%d.%d\n",
348
  * @ret rc		Return status code
407
  * @ret rc		Return status code
349
  */
408
  */
350
 static int intelxl_admin_driver ( struct intelxl_nic *intelxl ) {
409
 static int intelxl_admin_driver ( struct intelxl_nic *intelxl ) {
351
-	struct intelxl_admin_descriptor cmd;
352
-	struct intelxl_admin_driver_params *driver = &cmd.params.driver;
353
-	struct intelxl_admin_driver_buffer *buf =
354
-		&intelxl->command.buffer->driver;
410
+	struct intelxl_admin_descriptor *cmd;
411
+	struct intelxl_admin_driver_params *driver;
412
+	union intelxl_admin_buffer *buf;
355
 	int rc;
413
 	int rc;
356
 
414
 
357
 	/* Populate descriptor */
415
 	/* Populate descriptor */
358
-	memset ( &cmd, 0, sizeof ( cmd ) );
359
-	cmd.opcode = cpu_to_le16 ( INTELXL_ADMIN_DRIVER );
360
-	cmd.flags = cpu_to_le16 ( INTELXL_ADMIN_FL_RD | INTELXL_ADMIN_FL_BUF );
361
-	cmd.len = cpu_to_le16 ( sizeof ( *buf ) );
416
+	cmd = intelxl_admin_command_descriptor ( intelxl );
417
+	cmd->opcode = cpu_to_le16 ( INTELXL_ADMIN_DRIVER );
418
+	cmd->flags = cpu_to_le16 ( INTELXL_ADMIN_FL_RD | INTELXL_ADMIN_FL_BUF );
419
+	cmd->len = cpu_to_le16 ( sizeof ( buf->driver ) );
420
+	driver = &cmd->params.driver;
362
 	driver->major = product_major_version;
421
 	driver->major = product_major_version;
363
 	driver->minor = product_minor_version;
422
 	driver->minor = product_minor_version;
364
-	snprintf ( buf->name, sizeof ( buf->name ), "%s",
423
+	buf = intelxl_admin_command_buffer ( intelxl );
424
+	snprintf ( buf->driver.name, sizeof ( buf->driver.name ), "%s",
365
 		   ( product_name[0] ? product_name : product_short_name ) );
425
 		   ( product_name[0] ? product_name : product_short_name ) );
366
 
426
 
367
 	/* Issue command */
427
 	/* Issue command */
368
-	if ( ( rc = intelxl_admin_command ( intelxl, &cmd ) ) != 0 )
428
+	if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
369
 		return rc;
429
 		return rc;
370
 
430
 
371
 	return 0;
431
 	return 0;
378
  * @ret rc		Return status code
438
  * @ret rc		Return status code
379
  */
439
  */
380
 static int intelxl_admin_shutdown ( struct intelxl_nic *intelxl ) {
440
 static int intelxl_admin_shutdown ( struct intelxl_nic *intelxl ) {
381
-	struct intelxl_admin_descriptor cmd;
382
-	struct intelxl_admin_shutdown_params *shutdown = &cmd.params.shutdown;
441
+	struct intelxl_admin_descriptor *cmd;
442
+	struct intelxl_admin_shutdown_params *shutdown;
383
 	int rc;
443
 	int rc;
384
 
444
 
385
 	/* Populate descriptor */
445
 	/* Populate descriptor */
386
-	memset ( &cmd, 0, sizeof ( cmd ) );
387
-	cmd.opcode = cpu_to_le16 ( INTELXL_ADMIN_SHUTDOWN );
446
+	cmd = intelxl_admin_command_descriptor ( intelxl );
447
+	cmd->opcode = cpu_to_le16 ( INTELXL_ADMIN_SHUTDOWN );
448
+	shutdown = &cmd->params.shutdown;
388
 	shutdown->unloading = INTELXL_ADMIN_SHUTDOWN_UNLOADING;
449
 	shutdown->unloading = INTELXL_ADMIN_SHUTDOWN_UNLOADING;
389
 
450
 
390
 	/* Issue command */
451
 	/* Issue command */
391
-	if ( ( rc = intelxl_admin_command ( intelxl, &cmd ) ) != 0 )
452
+	if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
392
 		return rc;
453
 		return rc;
393
 
454
 
394
 	return 0;
455
 	return 0;
401
  * @ret rc		Return status code
462
  * @ret rc		Return status code
402
  */
463
  */
403
 static int intelxl_admin_switch ( struct intelxl_nic *intelxl ) {
464
 static int intelxl_admin_switch ( struct intelxl_nic *intelxl ) {
404
-	struct intelxl_admin_descriptor cmd;
405
-	struct intelxl_admin_switch_params *sw = &cmd.params.sw;
406
-	struct intelxl_admin_switch_buffer *buf = &intelxl->command.buffer->sw;
407
-	struct intelxl_admin_switch_config *cfg = &buf->cfg;
465
+	struct intelxl_admin_descriptor *cmd;
466
+	struct intelxl_admin_switch_params *sw;
467
+	union intelxl_admin_buffer *buf;
408
 	int rc;
468
 	int rc;
409
 
469
 
410
 	/* Populate descriptor */
470
 	/* Populate descriptor */
411
-	memset ( &cmd, 0, sizeof ( cmd ) );
412
-	cmd.opcode = cpu_to_le16 ( INTELXL_ADMIN_SWITCH );
413
-	cmd.flags = cpu_to_le16 ( INTELXL_ADMIN_FL_BUF );
414
-	cmd.len = cpu_to_le16 ( sizeof ( *buf ) );
471
+	cmd = intelxl_admin_command_descriptor ( intelxl );
472
+	cmd->opcode = cpu_to_le16 ( INTELXL_ADMIN_SWITCH );
473
+	cmd->flags = cpu_to_le16 ( INTELXL_ADMIN_FL_BUF );
474
+	cmd->len = cpu_to_le16 ( sizeof ( buf->sw ) );
475
+	sw = &cmd->params.sw;
476
+	buf = intelxl_admin_command_buffer ( intelxl );
415
 
477
 
416
 	/* Get each configuration in turn */
478
 	/* Get each configuration in turn */
417
 	do {
479
 	do {
418
 		/* Issue command */
480
 		/* Issue command */
419
-		if ( ( rc = intelxl_admin_command ( intelxl, &cmd ) ) != 0 )
481
+		if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
420
 			return rc;
482
 			return rc;
421
 
483
 
422
 		/* Dump raw configuration */
484
 		/* Dump raw configuration */
423
 		DBGC2 ( intelxl, "INTELXL %p SEID %#04x:\n",
485
 		DBGC2 ( intelxl, "INTELXL %p SEID %#04x:\n",
424
-			intelxl, le16_to_cpu ( cfg->seid ) );
425
-		DBGC2_HDA ( intelxl, 0, cfg, sizeof ( *cfg ) );
486
+			intelxl, le16_to_cpu ( buf->sw.cfg.seid ) );
487
+		DBGC2_HDA ( intelxl, 0, &buf->sw.cfg, sizeof ( buf->sw.cfg ) );
426
 
488
 
427
 		/* Parse response */
489
 		/* Parse response */
428
-		if ( cfg->type == INTELXL_ADMIN_SWITCH_TYPE_VSI ) {
429
-			intelxl->vsi = le16_to_cpu ( cfg->seid );
490
+		if ( buf->sw.cfg.type == INTELXL_ADMIN_SWITCH_TYPE_VSI ) {
491
+			intelxl->vsi = le16_to_cpu ( buf->sw.cfg.seid );
430
 			DBGC ( intelxl, "INTELXL %p VSI %#04x uplink %#04x "
492
 			DBGC ( intelxl, "INTELXL %p VSI %#04x uplink %#04x "
431
 			       "downlink %#04x conn %#02x\n", intelxl,
493
 			       "downlink %#04x conn %#02x\n", intelxl,
432
-			       intelxl->vsi, le16_to_cpu ( cfg->uplink ),
433
-			       le16_to_cpu ( cfg->downlink ), cfg->connection );
494
+			       intelxl->vsi, le16_to_cpu ( buf->sw.cfg.uplink ),
495
+			       le16_to_cpu ( buf->sw.cfg.downlink ),
496
+			       buf->sw.cfg.connection );
434
 		}
497
 		}
435
 
498
 
436
 	} while ( sw->next );
499
 	} while ( sw->next );
451
  * @ret rc		Return status code
514
  * @ret rc		Return status code
452
  */
515
  */
453
 static int intelxl_admin_vsi ( struct intelxl_nic *intelxl ) {
516
 static int intelxl_admin_vsi ( struct intelxl_nic *intelxl ) {
454
-	struct intelxl_admin_descriptor cmd;
455
-	struct intelxl_admin_vsi_params *vsi = &cmd.params.vsi;
456
-	struct intelxl_admin_vsi_buffer *buf = &intelxl->command.buffer->vsi;
517
+	struct intelxl_admin_descriptor *cmd;
518
+	struct intelxl_admin_vsi_params *vsi;
519
+	union intelxl_admin_buffer *buf;
457
 	int rc;
520
 	int rc;
458
 
521
 
459
 	/* Populate descriptor */
522
 	/* Populate descriptor */
460
-	memset ( &cmd, 0, sizeof ( cmd ) );
461
-	cmd.opcode = cpu_to_le16 ( INTELXL_ADMIN_VSI );
462
-	cmd.flags = cpu_to_le16 ( INTELXL_ADMIN_FL_BUF );
463
-	cmd.len = cpu_to_le16 ( sizeof ( *buf ) );
523
+	cmd = intelxl_admin_command_descriptor ( intelxl );
524
+	cmd->opcode = cpu_to_le16 ( INTELXL_ADMIN_VSI );
525
+	cmd->flags = cpu_to_le16 ( INTELXL_ADMIN_FL_BUF );
526
+	cmd->len = cpu_to_le16 ( sizeof ( buf->vsi ) );
527
+	vsi = &cmd->params.vsi;
464
 	vsi->vsi = cpu_to_le16 ( intelxl->vsi );
528
 	vsi->vsi = cpu_to_le16 ( intelxl->vsi );
529
+	buf = intelxl_admin_command_buffer ( intelxl );
465
 
530
 
466
 	/* Issue command */
531
 	/* Issue command */
467
-	if ( ( rc = intelxl_admin_command ( intelxl, &cmd ) ) != 0 )
532
+	if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
468
 		return rc;
533
 		return rc;
469
 
534
 
470
 	/* Parse response */
535
 	/* Parse response */
471
-	intelxl->queue = le16_to_cpu ( buf->queue[0] );
472
-	intelxl->qset = le16_to_cpu ( buf->qset[0] );
536
+	intelxl->queue = le16_to_cpu ( buf->vsi.queue[0] );
537
+	intelxl->qset = le16_to_cpu ( buf->vsi.qset[0] );
473
 	DBGC ( intelxl, "INTELXL %p VSI %#04x queue %#04x qset %#04x\n",
538
 	DBGC ( intelxl, "INTELXL %p VSI %#04x queue %#04x qset %#04x\n",
474
 	       intelxl, intelxl->vsi, intelxl->queue, intelxl->qset );
539
 	       intelxl, intelxl->vsi, intelxl->queue, intelxl->qset );
475
 
540
 
483
  * @ret rc		Return status code
548
  * @ret rc		Return status code
484
  */
549
  */
485
 static int intelxl_admin_promisc ( struct intelxl_nic *intelxl ) {
550
 static int intelxl_admin_promisc ( struct intelxl_nic *intelxl ) {
486
-	struct intelxl_admin_descriptor cmd;
487
-	struct intelxl_admin_promisc_params *promisc = &cmd.params.promisc;
551
+	struct intelxl_admin_descriptor *cmd;
552
+	struct intelxl_admin_promisc_params *promisc;
488
 	uint16_t flags;
553
 	uint16_t flags;
489
 	int rc;
554
 	int rc;
490
 
555
 
491
 	/* Populate descriptor */
556
 	/* Populate descriptor */
492
-	memset ( &cmd, 0, sizeof ( cmd ) );
493
-	cmd.opcode = cpu_to_le16 ( INTELXL_ADMIN_PROMISC );
557
+	cmd = intelxl_admin_command_descriptor ( intelxl );
558
+	cmd->opcode = cpu_to_le16 ( INTELXL_ADMIN_PROMISC );
494
 	flags = ( INTELXL_ADMIN_PROMISC_FL_UNICAST |
559
 	flags = ( INTELXL_ADMIN_PROMISC_FL_UNICAST |
495
 		  INTELXL_ADMIN_PROMISC_FL_MULTICAST |
560
 		  INTELXL_ADMIN_PROMISC_FL_MULTICAST |
496
 		  INTELXL_ADMIN_PROMISC_FL_BROADCAST |
561
 		  INTELXL_ADMIN_PROMISC_FL_BROADCAST |
497
 		  INTELXL_ADMIN_PROMISC_FL_VLAN );
562
 		  INTELXL_ADMIN_PROMISC_FL_VLAN );
563
+	promisc = &cmd->params.promisc;
498
 	promisc->flags = cpu_to_le16 ( flags );
564
 	promisc->flags = cpu_to_le16 ( flags );
499
 	promisc->valid = cpu_to_le16 ( flags );
565
 	promisc->valid = cpu_to_le16 ( flags );
500
 	promisc->vsi = cpu_to_le16 ( intelxl->vsi );
566
 	promisc->vsi = cpu_to_le16 ( intelxl->vsi );
501
 
567
 
502
 	/* Issue command */
568
 	/* Issue command */
503
-	if ( ( rc = intelxl_admin_command ( intelxl, &cmd ) ) != 0 )
569
+	if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
504
 		return rc;
570
 		return rc;
505
 
571
 
506
 	return 0;
572
 	return 0;
513
  * @ret rc		Return status code
579
  * @ret rc		Return status code
514
  */
580
  */
515
 static int intelxl_admin_autoneg ( struct intelxl_nic *intelxl ) {
581
 static int intelxl_admin_autoneg ( struct intelxl_nic *intelxl ) {
516
-	struct intelxl_admin_descriptor cmd;
517
-	struct intelxl_admin_autoneg_params *autoneg = &cmd.params.autoneg;
582
+	struct intelxl_admin_descriptor *cmd;
583
+	struct intelxl_admin_autoneg_params *autoneg;
518
 	int rc;
584
 	int rc;
519
 
585
 
520
 	/* Populate descriptor */
586
 	/* Populate descriptor */
521
-	memset ( &cmd, 0, sizeof ( cmd ) );
522
-	cmd.opcode = cpu_to_le16 ( INTELXL_ADMIN_AUTONEG );
587
+	cmd = intelxl_admin_command_descriptor ( intelxl );
588
+	cmd->opcode = cpu_to_le16 ( INTELXL_ADMIN_AUTONEG );
589
+	autoneg = &cmd->params.autoneg;
523
 	autoneg->flags = ( INTELXL_ADMIN_AUTONEG_FL_RESTART |
590
 	autoneg->flags = ( INTELXL_ADMIN_AUTONEG_FL_RESTART |
524
 			   INTELXL_ADMIN_AUTONEG_FL_ENABLE );
591
 			   INTELXL_ADMIN_AUTONEG_FL_ENABLE );
525
 
592
 
526
 	/* Issue command */
593
 	/* Issue command */
527
-	if ( ( rc = intelxl_admin_command ( intelxl, &cmd ) ) != 0 )
594
+	if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
528
 		return rc;
595
 		return rc;
529
 
596
 
530
 	return 0;
597
 	return 0;
538
  */
605
  */
539
 static int intelxl_admin_link ( struct net_device *netdev ) {
606
 static int intelxl_admin_link ( struct net_device *netdev ) {
540
 	struct intelxl_nic *intelxl = netdev->priv;
607
 	struct intelxl_nic *intelxl = netdev->priv;
541
-	struct intelxl_admin_descriptor cmd;
542
-	struct intelxl_admin_link_params *link = &cmd.params.link;
608
+	struct intelxl_admin_descriptor *cmd;
609
+	struct intelxl_admin_link_params *link;
543
 	int rc;
610
 	int rc;
544
 
611
 
545
 	/* Populate descriptor */
612
 	/* Populate descriptor */
546
-	memset ( &cmd, 0, sizeof ( cmd ) );
547
-	cmd.opcode = cpu_to_le16 ( INTELXL_ADMIN_LINK );
613
+	cmd = intelxl_admin_command_descriptor ( intelxl );
614
+	cmd->opcode = cpu_to_le16 ( INTELXL_ADMIN_LINK );
615
+	link = &cmd->params.link;
548
 	link->notify = INTELXL_ADMIN_LINK_NOTIFY;
616
 	link->notify = INTELXL_ADMIN_LINK_NOTIFY;
549
 
617
 
550
 	/* Issue command */
618
 	/* Issue command */
551
-	if ( ( rc = intelxl_admin_command ( intelxl, &cmd ) ) != 0 )
619
+	if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
552
 		return rc;
620
 		return rc;
553
 	DBGC ( intelxl, "INTELXL %p PHY %#02x speed %#02x status %#02x\n",
621
 	DBGC ( intelxl, "INTELXL %p PHY %#02x speed %#02x status %#02x\n",
554
 	       intelxl, link->phy, link->speed, link->status );
622
 	       intelxl, link->phy, link->speed, link->status );
577
 	/* Update tail pointer */
645
 	/* Update tail pointer */
578
 	tail = ( ( admin->index + INTELXL_ADMIN_NUM_DESC - 1 ) %
646
 	tail = ( ( admin->index + INTELXL_ADMIN_NUM_DESC - 1 ) %
579
 		 INTELXL_ADMIN_NUM_DESC );
647
 		 INTELXL_ADMIN_NUM_DESC );
648
+	wmb();
580
 	writel ( tail, admin_regs + regs->tail );
649
 	writel ( tail, admin_regs + regs->tail );
581
 }
650
 }
582
 
651
 
588
 static void intelxl_poll_admin ( struct net_device *netdev ) {
657
 static void intelxl_poll_admin ( struct net_device *netdev ) {
589
 	struct intelxl_nic *intelxl = netdev->priv;
658
 	struct intelxl_nic *intelxl = netdev->priv;
590
 	struct intelxl_admin *admin = &intelxl->event;
659
 	struct intelxl_admin *admin = &intelxl->event;
591
-	struct intelxl_admin_descriptor *desc;
660
+	struct intelxl_admin_descriptor *evt;
661
+	union intelxl_admin_buffer *buf;
592
 
662
 
593
 	/* Check for events */
663
 	/* Check for events */
594
 	while ( 1 ) {
664
 	while ( 1 ) {
595
 
665
 
596
-		/* Get next event descriptor */
597
-		desc = &admin->desc[admin->index % INTELXL_ADMIN_NUM_DESC];
666
+		/* Get next event descriptor and data buffer */
667
+		evt = &admin->desc[ admin->index % INTELXL_ADMIN_NUM_DESC ];
668
+		buf = &admin->buf[ admin->index % INTELXL_ADMIN_NUM_DESC ];
598
 
669
 
599
 		/* Stop if descriptor is not yet completed */
670
 		/* Stop if descriptor is not yet completed */
600
-		if ( ! ( desc->flags & INTELXL_ADMIN_FL_DD ) )
671
+		if ( ! ( evt->flags & INTELXL_ADMIN_FL_DD ) )
601
 			return;
672
 			return;
602
 		DBGC2 ( intelxl, "INTELXL %p admin event %#x:\n",
673
 		DBGC2 ( intelxl, "INTELXL %p admin event %#x:\n",
603
 			intelxl, admin->index );
674
 			intelxl, admin->index );
604
-		DBGC2_HDA ( intelxl, virt_to_phys ( desc ), desc,
605
-			    sizeof ( *desc ) );
675
+		DBGC2_HDA ( intelxl, virt_to_phys ( evt ), evt,
676
+			    sizeof ( *evt ) );
677
+		if ( evt->flags & cpu_to_le16 ( INTELXL_ADMIN_FL_BUF ) ) {
678
+			DBGC2_HDA ( intelxl, virt_to_phys ( buf ), buf,
679
+				    le16_to_cpu ( evt->len ) );
680
+		}
606
 
681
 
607
 		/* Handle event */
682
 		/* Handle event */
608
-		switch ( desc->opcode ) {
683
+		switch ( evt->opcode ) {
609
 		case cpu_to_le16 ( INTELXL_ADMIN_LINK ):
684
 		case cpu_to_le16 ( INTELXL_ADMIN_LINK ):
610
 			intelxl_admin_link ( netdev );
685
 			intelxl_admin_link ( netdev );
611
 			break;
686
 			break;
612
 		default:
687
 		default:
613
 			DBGC ( intelxl, "INTELXL %p admin event %#x "
688
 			DBGC ( intelxl, "INTELXL %p admin event %#x "
614
 			       "unrecognised opcode %#04x\n", intelxl,
689
 			       "unrecognised opcode %#04x\n", intelxl,
615
-			       admin->index, le16_to_cpu ( desc->opcode ) );
690
+			       admin->index, le16_to_cpu ( evt->opcode ) );
616
 			break;
691
 			break;
617
 		}
692
 		}
618
 
693
 
619
-		/* Clear event completion flag */
620
-		desc->flags = 0;
621
-		wmb();
622
-
623
-		/* Update index and refill queue */
694
+		/* Reset descriptor and refill queue */
695
+		intelxl_admin_event_init ( intelxl, admin->index );
624
 		admin->index++;
696
 		admin->index++;
625
 		intelxl_refill_admin ( intelxl );
697
 		intelxl_refill_admin ( intelxl );
626
 	}
698
 	}
633
  * @ret rc		Return status code
705
  * @ret rc		Return status code
634
  */
706
  */
635
 static int intelxl_open_admin ( struct intelxl_nic *intelxl ) {
707
 static int intelxl_open_admin ( struct intelxl_nic *intelxl ) {
708
+	unsigned int i;
636
 	int rc;
709
 	int rc;
637
 
710
 
638
 	/* Create admin event queue */
711
 	/* Create admin event queue */
643
 	if ( ( rc = intelxl_create_admin ( intelxl, &intelxl->command ) ) != 0 )
716
 	if ( ( rc = intelxl_create_admin ( intelxl, &intelxl->command ) ) != 0 )
644
 		goto err_create_command;
717
 		goto err_create_command;
645
 
718
 
719
+	/* Initialise all admin event queue descriptors */
720
+	for ( i = 0 ; i < INTELXL_ADMIN_NUM_DESC ; i++ )
721
+		intelxl_admin_event_init ( intelxl, i );
722
+
646
 	/* Post all descriptors to event queue */
723
 	/* Post all descriptors to event queue */
647
 	intelxl_refill_admin ( intelxl );
724
 	intelxl_refill_admin ( intelxl );
648
 
725
 

+ 4
- 2
src/drivers/net/intelxl.h View File

319
 	struct intelxl_admin_switch_buffer sw;
319
 	struct intelxl_admin_switch_buffer sw;
320
 	/** Get VSI Parameters data buffer */
320
 	/** Get VSI Parameters data buffer */
321
 	struct intelxl_admin_vsi_buffer vsi;
321
 	struct intelxl_admin_vsi_buffer vsi;
322
+	/** Alignment padding */
323
+	uint8_t pad[INTELXL_ALIGN];
322
 } __attribute__ (( packed ));
324
 } __attribute__ (( packed ));
323
 
325
 
324
 /** Admin queue descriptor */
326
 /** Admin queue descriptor */
358
 struct intelxl_admin {
360
 struct intelxl_admin {
359
 	/** Descriptors */
361
 	/** Descriptors */
360
 	struct intelxl_admin_descriptor *desc;
362
 	struct intelxl_admin_descriptor *desc;
363
+	/** Data buffers */
364
+	union intelxl_admin_buffer *buf;
361
 	/** Queue index */
365
 	/** Queue index */
362
 	unsigned int index;
366
 	unsigned int index;
363
 
367
 
365
 	unsigned int base;
369
 	unsigned int base;
366
 	/** Register offsets */
370
 	/** Register offsets */
367
 	const struct intelxl_admin_offsets *regs;
371
 	const struct intelxl_admin_offsets *regs;
368
-	/** Data buffer */
369
-	union intelxl_admin_buffer *buffer;
370
 };
372
 };
371
 
373
 
372
 /**
374
 /**

Loading…
Cancel
Save