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,17 +141,17 @@ static const struct intelxl_admin_offsets intelxl_admin_offsets = {
141 141
  */
142 142
 static int intelxl_create_admin ( struct intelxl_nic *intelxl,
143 143
 				  struct intelxl_admin *admin ) {
144
+	size_t buf_len = ( sizeof ( admin->buf[0] ) * INTELXL_ADMIN_NUM_DESC );
144 145
 	size_t len = ( sizeof ( admin->desc[0] ) * INTELXL_ADMIN_NUM_DESC );
145 146
 	const struct intelxl_admin_offsets *regs = admin->regs;
146 147
 	void *admin_regs = ( intelxl->regs + admin->base );
147 148
 	physaddr_t address;
148 149
 
149 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 153
 		return -ENOMEM;
154
-	admin->buffer = ( ( ( void * ) admin->desc ) + len );
154
+	admin->desc = ( ( ( void * ) admin->buf ) + buf_len );
155 155
 
156 156
 	/* Initialise admin queue */
157 157
 	memset ( admin->desc, 0, len );
@@ -183,9 +183,9 @@ static int intelxl_create_admin ( struct intelxl_nic *intelxl,
183 183
 	       ( ( admin == &intelxl->command ) ? 'T' : 'R' ),
184 184
 	       ( ( unsigned long long ) address ),
185 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 189
 	return 0;
190 190
 }
191 191
 
@@ -197,6 +197,7 @@ static int intelxl_create_admin ( struct intelxl_nic *intelxl,
197 197
  */
198 198
 static void intelxl_destroy_admin ( struct intelxl_nic *intelxl,
199 199
 				    struct intelxl_admin *admin ) {
200
+	size_t buf_len = ( sizeof ( admin->buf[0] ) * INTELXL_ADMIN_NUM_DESC );
200 201
 	size_t len = ( sizeof ( admin->desc[0] ) * INTELXL_ADMIN_NUM_DESC );
201 202
 	const struct intelxl_admin_offsets *regs = admin->regs;
202 203
 	void *admin_regs = ( intelxl->regs + admin->base );
@@ -205,23 +206,80 @@ static void intelxl_destroy_admin ( struct intelxl_nic *intelxl,
205 206
 	writel ( 0, admin_regs + regs->len );
206 207
 
207 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 270
  * Issue admin queue command
213 271
  *
214 272
  * @v intelxl		Intel device
215
- * @v cmd		Command descriptor
216 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 276
 	struct intelxl_admin *admin = &intelxl->command;
221 277
 	const struct intelxl_admin_offsets *regs = admin->regs;
222 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 283
 	unsigned int index;
226 284
 	unsigned int tail;
227 285
 	unsigned int i;
@@ -230,32 +288,36 @@ static int intelxl_admin_command ( struct intelxl_nic *intelxl,
230 288
 	/* Get next queue entry */
231 289
 	index = admin->index++;
232 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 302
 	/* Populate data buffer address if applicable */
247 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 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 321
 	wmb();
260 322
 	writel ( tail, admin_regs + regs->tail );
261 323
 
@@ -263,36 +325,33 @@ static int intelxl_admin_command ( struct intelxl_nic *intelxl,
263 325
 	for ( i = 0 ; i < INTELXL_ADMIN_MAX_WAIT_MS ; i++ ) {
264 326
 
265 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 329
 			mdelay ( 1 );
268 330
 			continue;
269 331
 		}
270 332
 		DBGC2 ( intelxl, "INTELXL %p admin command %#x response:\n",
271 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 337
 		/* Check for cookie mismatch */
276
-		if ( desc->cookie != cmd->cookie ) {
338
+		if ( cmd->cookie != cookie ) {
277 339
 			DBGC ( intelxl, "INTELXL %p admin command %#x bad "
278 340
 			       "cookie %#x\n", intelxl, index,
279
-			       le32_to_cpu ( desc->cookie ) );
341
+			       le32_to_cpu ( cmd->cookie ) );
280 342
 			rc = -EPROTO;
281 343
 			goto err;
282 344
 		}
283 345
 
284 346
 		/* Check for errors */
285
-		if ( desc->ret != 0 ) {
347
+		if ( cmd->ret != 0 ) {
286 348
 			DBGC ( intelxl, "INTELXL %p admin command %#x error "
287 349
 			       "%d\n", intelxl, index,
288
-			       le16_to_cpu ( desc->ret ) );
350
+			       le16_to_cpu ( cmd->ret ) );
289 351
 			rc = -EIO;
290 352
 			goto err;
291 353
 		}
292 354
 
293
-		/* Copy response back to command descriptor */
294
-		memcpy ( cmd, desc, sizeof ( *cmd ) );
295
-
296 355
 		/* Success */
297 356
 		return 0;
298 357
 	}
@@ -301,8 +360,7 @@ static int intelxl_admin_command ( struct intelxl_nic *intelxl,
301 360
 	DBGC ( intelxl, "INTELXL %p timed out waiting for admin command %#x:\n",
302 361
 	       intelxl, index );
303 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 364
 	return rc;
307 365
 }
308 366
 
@@ -313,17 +371,18 @@ static int intelxl_admin_command ( struct intelxl_nic *intelxl,
313 371
  * @ret rc		Return status code
314 372
  */
315 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 376
 	unsigned int api;
319 377
 	int rc;
320 378
 
321 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 384
 	/* Issue command */
326
-	if ( ( rc = intelxl_admin_command ( intelxl, &cmd ) ) != 0 )
385
+	if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
327 386
 		return rc;
328 387
 	api = le16_to_cpu ( version->api.major );
329 388
 	DBGC ( intelxl, "INTELXL %p firmware v%d.%d API v%d.%d\n",
@@ -348,24 +407,25 @@ static int intelxl_admin_version ( struct intelxl_nic *intelxl ) {
348 407
  * @ret rc		Return status code
349 408
  */
350 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 413
 	int rc;
356 414
 
357 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 421
 	driver->major = product_major_version;
363 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 425
 		   ( product_name[0] ? product_name : product_short_name ) );
366 426
 
367 427
 	/* Issue command */
368
-	if ( ( rc = intelxl_admin_command ( intelxl, &cmd ) ) != 0 )
428
+	if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
369 429
 		return rc;
370 430
 
371 431
 	return 0;
@@ -378,17 +438,18 @@ static int intelxl_admin_driver ( struct intelxl_nic *intelxl ) {
378 438
  * @ret rc		Return status code
379 439
  */
380 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 443
 	int rc;
384 444
 
385 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 449
 	shutdown->unloading = INTELXL_ADMIN_SHUTDOWN_UNLOADING;
389 450
 
390 451
 	/* Issue command */
391
-	if ( ( rc = intelxl_admin_command ( intelxl, &cmd ) ) != 0 )
452
+	if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
392 453
 		return rc;
393 454
 
394 455
 	return 0;
@@ -401,36 +462,38 @@ static int intelxl_admin_shutdown ( struct intelxl_nic *intelxl ) {
401 462
  * @ret rc		Return status code
402 463
  */
403 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 468
 	int rc;
409 469
 
410 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 478
 	/* Get each configuration in turn */
417 479
 	do {
418 480
 		/* Issue command */
419
-		if ( ( rc = intelxl_admin_command ( intelxl, &cmd ) ) != 0 )
481
+		if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
420 482
 			return rc;
421 483
 
422 484
 		/* Dump raw configuration */
423 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 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 492
 			DBGC ( intelxl, "INTELXL %p VSI %#04x uplink %#04x "
431 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 499
 	} while ( sw->next );
@@ -451,25 +514,27 @@ static int intelxl_admin_switch ( struct intelxl_nic *intelxl ) {
451 514
  * @ret rc		Return status code
452 515
  */
453 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 520
 	int rc;
458 521
 
459 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 528
 	vsi->vsi = cpu_to_le16 ( intelxl->vsi );
529
+	buf = intelxl_admin_command_buffer ( intelxl );
465 530
 
466 531
 	/* Issue command */
467
-	if ( ( rc = intelxl_admin_command ( intelxl, &cmd ) ) != 0 )
532
+	if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
468 533
 		return rc;
469 534
 
470 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 538
 	DBGC ( intelxl, "INTELXL %p VSI %#04x queue %#04x qset %#04x\n",
474 539
 	       intelxl, intelxl->vsi, intelxl->queue, intelxl->qset );
475 540
 
@@ -483,24 +548,25 @@ static int intelxl_admin_vsi ( struct intelxl_nic *intelxl ) {
483 548
  * @ret rc		Return status code
484 549
  */
485 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 553
 	uint16_t flags;
489 554
 	int rc;
490 555
 
491 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 559
 	flags = ( INTELXL_ADMIN_PROMISC_FL_UNICAST |
495 560
 		  INTELXL_ADMIN_PROMISC_FL_MULTICAST |
496 561
 		  INTELXL_ADMIN_PROMISC_FL_BROADCAST |
497 562
 		  INTELXL_ADMIN_PROMISC_FL_VLAN );
563
+	promisc = &cmd->params.promisc;
498 564
 	promisc->flags = cpu_to_le16 ( flags );
499 565
 	promisc->valid = cpu_to_le16 ( flags );
500 566
 	promisc->vsi = cpu_to_le16 ( intelxl->vsi );
501 567
 
502 568
 	/* Issue command */
503
-	if ( ( rc = intelxl_admin_command ( intelxl, &cmd ) ) != 0 )
569
+	if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
504 570
 		return rc;
505 571
 
506 572
 	return 0;
@@ -513,18 +579,19 @@ static int intelxl_admin_promisc ( struct intelxl_nic *intelxl ) {
513 579
  * @ret rc		Return status code
514 580
  */
515 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 584
 	int rc;
519 585
 
520 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 590
 	autoneg->flags = ( INTELXL_ADMIN_AUTONEG_FL_RESTART |
524 591
 			   INTELXL_ADMIN_AUTONEG_FL_ENABLE );
525 592
 
526 593
 	/* Issue command */
527
-	if ( ( rc = intelxl_admin_command ( intelxl, &cmd ) ) != 0 )
594
+	if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
528 595
 		return rc;
529 596
 
530 597
 	return 0;
@@ -538,17 +605,18 @@ static int intelxl_admin_autoneg ( struct intelxl_nic *intelxl ) {
538 605
  */
539 606
 static int intelxl_admin_link ( struct net_device *netdev ) {
540 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 610
 	int rc;
544 611
 
545 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 616
 	link->notify = INTELXL_ADMIN_LINK_NOTIFY;
549 617
 
550 618
 	/* Issue command */
551
-	if ( ( rc = intelxl_admin_command ( intelxl, &cmd ) ) != 0 )
619
+	if ( ( rc = intelxl_admin_command ( intelxl ) ) != 0 )
552 620
 		return rc;
553 621
 	DBGC ( intelxl, "INTELXL %p PHY %#02x speed %#02x status %#02x\n",
554 622
 	       intelxl, link->phy, link->speed, link->status );
@@ -577,6 +645,7 @@ static void intelxl_refill_admin ( struct intelxl_nic *intelxl ) {
577 645
 	/* Update tail pointer */
578 646
 	tail = ( ( admin->index + INTELXL_ADMIN_NUM_DESC - 1 ) %
579 647
 		 INTELXL_ADMIN_NUM_DESC );
648
+	wmb();
580 649
 	writel ( tail, admin_regs + regs->tail );
581 650
 }
582 651
 
@@ -588,39 +657,42 @@ static void intelxl_refill_admin ( struct intelxl_nic *intelxl ) {
588 657
 static void intelxl_poll_admin ( struct net_device *netdev ) {
589 658
 	struct intelxl_nic *intelxl = netdev->priv;
590 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 663
 	/* Check for events */
594 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 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 672
 			return;
602 673
 		DBGC2 ( intelxl, "INTELXL %p admin event %#x:\n",
603 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 682
 		/* Handle event */
608
-		switch ( desc->opcode ) {
683
+		switch ( evt->opcode ) {
609 684
 		case cpu_to_le16 ( INTELXL_ADMIN_LINK ):
610 685
 			intelxl_admin_link ( netdev );
611 686
 			break;
612 687
 		default:
613 688
 			DBGC ( intelxl, "INTELXL %p admin event %#x "
614 689
 			       "unrecognised opcode %#04x\n", intelxl,
615
-			       admin->index, le16_to_cpu ( desc->opcode ) );
690
+			       admin->index, le16_to_cpu ( evt->opcode ) );
616 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 696
 		admin->index++;
625 697
 		intelxl_refill_admin ( intelxl );
626 698
 	}
@@ -633,6 +705,7 @@ static void intelxl_poll_admin ( struct net_device *netdev ) {
633 705
  * @ret rc		Return status code
634 706
  */
635 707
 static int intelxl_open_admin ( struct intelxl_nic *intelxl ) {
708
+	unsigned int i;
636 709
 	int rc;
637 710
 
638 711
 	/* Create admin event queue */
@@ -643,6 +716,10 @@ static int intelxl_open_admin ( struct intelxl_nic *intelxl ) {
643 716
 	if ( ( rc = intelxl_create_admin ( intelxl, &intelxl->command ) ) != 0 )
644 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 723
 	/* Post all descriptors to event queue */
647 724
 	intelxl_refill_admin ( intelxl );
648 725
 

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

@@ -319,6 +319,8 @@ union intelxl_admin_buffer {
319 319
 	struct intelxl_admin_switch_buffer sw;
320 320
 	/** Get VSI Parameters data buffer */
321 321
 	struct intelxl_admin_vsi_buffer vsi;
322
+	/** Alignment padding */
323
+	uint8_t pad[INTELXL_ALIGN];
322 324
 } __attribute__ (( packed ));
323 325
 
324 326
 /** Admin queue descriptor */
@@ -358,6 +360,8 @@ struct intelxl_admin_descriptor {
358 360
 struct intelxl_admin {
359 361
 	/** Descriptors */
360 362
 	struct intelxl_admin_descriptor *desc;
363
+	/** Data buffers */
364
+	union intelxl_admin_buffer *buf;
361 365
 	/** Queue index */
362 366
 	unsigned int index;
363 367
 
@@ -365,8 +369,6 @@ struct intelxl_admin {
365 369
 	unsigned int base;
366 370
 	/** Register offsets */
367 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