Browse Source

[intel] Reset all virtual function settings

Some VF data is not cleared with reset, so make sure to return all the
settings to default before configuring the VF.

This fixes an issue where network packets would fail to be received if
the VF was previously used by the linux ixgbevf driver.

Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Vishvananda Ishaya 7 years ago
parent
commit
1d04900262
4 changed files with 91 additions and 13 deletions
  1. 57
    6
      src/drivers/net/intel.c
  2. 4
    0
      src/drivers/net/intel.h
  3. 18
    5
      src/drivers/net/intelxvf.c
  4. 12
    2
      src/drivers/net/intelxvf.h

+ 57
- 6
src/drivers/net/intel.c View File

@@ -424,6 +424,61 @@ void intel_describe_rx ( struct intel_descriptor *rx, physaddr_t addr,
424 424
  ******************************************************************************
425 425
  */
426 426
 
427
+/**
428
+ * Disable descriptor ring
429
+ *
430
+ * @v intel		Intel device
431
+ * @v reg		Register block
432
+ * @ret rc		Return status code
433
+ */
434
+static int intel_disable_ring ( struct intel_nic *intel, unsigned int reg ) {
435
+	uint32_t dctl;
436
+	unsigned int i;
437
+
438
+	/* Disable ring */
439
+	writel ( 0, ( intel->regs + reg + INTEL_xDCTL ) );
440
+
441
+	/* Wait for disable to complete */
442
+	for ( i = 0 ; i < INTEL_DISABLE_MAX_WAIT_MS ; i++ ) {
443
+
444
+		/* Check if ring is disabled */
445
+		dctl = readl ( intel->regs + reg + INTEL_xDCTL );
446
+		if ( ! ( dctl & INTEL_xDCTL_ENABLE ) )
447
+			return 0;
448
+
449
+		/* Delay */
450
+		mdelay ( 1 );
451
+	}
452
+
453
+	DBGC ( intel, "INTEL %p ring %05x timed out waiting for disable "
454
+	       "(dctl %08x)\n", intel, reg, dctl );
455
+	return -ETIMEDOUT;
456
+}
457
+
458
+/**
459
+ * Reset descriptor ring
460
+ *
461
+ * @v intel		Intel device
462
+ * @v reg		Register block
463
+ * @ret rc		Return status code
464
+ */
465
+void intel_reset_ring ( struct intel_nic *intel, unsigned int reg ) {
466
+
467
+	/* Disable ring.  Ignore errors and continue to reset the ring anyway */
468
+	intel_disable_ring ( intel, reg );
469
+
470
+	/* Clear ring length */
471
+	writel ( 0, ( intel->regs + reg + INTEL_xDLEN ) );
472
+
473
+	/* Clear ring address */
474
+	writel ( 0, ( intel->regs + reg + INTEL_xDBAH ) );
475
+	writel ( 0, ( intel->regs + reg + INTEL_xDBAL ) );
476
+
477
+	/* Reset head and tail pointers */
478
+	writel ( 0, ( intel->regs + reg + INTEL_xDH ) );
479
+	writel ( 0, ( intel->regs + reg + INTEL_xDT ) );
480
+}
481
+
427 482
 /**
428 483
  * Create descriptor ring
429 484
  *
@@ -484,12 +539,8 @@ int intel_create_ring ( struct intel_nic *intel, struct intel_ring *ring ) {
484 539
  */
485 540
 void intel_destroy_ring ( struct intel_nic *intel, struct intel_ring *ring ) {
486 541
 
487
-	/* Clear ring length */
488
-	writel ( 0, ( intel->regs + ring->reg + INTEL_xDLEN ) );
489
-
490
-	/* Clear ring address */
491
-	writel ( 0, ( intel->regs + ring->reg + INTEL_xDBAL ) );
492
-	writel ( 0, ( intel->regs + ring->reg + INTEL_xDBAH ) );
542
+	/* Reset ring */
543
+	intel_reset_ring ( intel, ring->reg );
493 544
 
494 545
 	/* Free descriptor ring */
495 546
 	free_dma ( ring->desc, ring->len );

+ 4
- 0
src/drivers/net/intel.h View File

@@ -185,6 +185,9 @@ struct intel_descriptor {
185 185
 #define INTEL_xDCTL 0x28
186 186
 #define INTEL_xDCTL_ENABLE	0x02000000UL	/**< Queue enable */
187 187
 
188
+/** Maximum time to wait for queue disable, in milliseconds */
189
+#define INTEL_DISABLE_MAX_WAIT_MS 100
190
+
188 191
 /** Receive Address Low */
189 192
 #define INTEL_RAL0 0x05400UL
190 193
 
@@ -330,6 +333,7 @@ extern void intel_describe_tx_adv ( struct intel_descriptor *tx,
330 333
 				    physaddr_t addr, size_t len );
331 334
 extern void intel_describe_rx ( struct intel_descriptor *rx,
332 335
 				physaddr_t addr, size_t len );
336
+extern void intel_reset_ring ( struct intel_nic *intel, unsigned int reg );
333 337
 extern int intel_create_ring ( struct intel_nic *intel,
334 338
 			       struct intel_ring *ring );
335 339
 extern void intel_destroy_ring ( struct intel_nic *intel,

+ 18
- 5
src/drivers/net/intelxvf.c View File

@@ -216,6 +216,7 @@ static int intelxvf_open ( struct net_device *netdev ) {
216 216
 	uint32_t rxdctl;
217 217
 	uint32_t srrctl;
218 218
 	uint32_t dca_rxctrl;
219
+	unsigned int i;
219 220
 	int vlan_thing;
220 221
 	int rc;
221 222
 
@@ -252,6 +253,15 @@ static int intelxvf_open ( struct net_device *netdev ) {
252 253
 		goto err_mbox_set_mtu;
253 254
 	}
254 255
 
256
+	/* Reset all descriptor rings */
257
+	for ( i = 0 ; i < INTELXVF_NUM_RINGS ; i++ ) {
258
+		intel_reset_ring ( intel, INTELXVF_TD ( i ) );
259
+		intel_reset_ring ( intel, INTELXVF_RD ( i ) );
260
+	}
261
+
262
+	/* Reset packet split receive type register */
263
+	writel ( 0, intel->regs + INTELXVF_PSRTYPE );
264
+
255 265
 	/* Get queue configuration.  Ignore failures, since the host
256 266
 	 * may not support this message.
257 267
 	 */
@@ -260,9 +270,9 @@ static int intelxvf_open ( struct net_device *netdev ) {
260 270
 	if ( vlan_thing ) {
261 271
 		DBGC ( intel, "INTEL %p stripping VLAN tags (thing=%d)\n",
262 272
 		       intel, vlan_thing );
263
-		rxdctl = readl ( intel->regs + INTELXVF_RD + INTEL_xDCTL );
273
+		rxdctl = readl ( intel->regs + INTELXVF_RD(0) + INTEL_xDCTL );
264 274
 		rxdctl |= INTELX_RXDCTL_VME;
265
-		writel ( rxdctl, intel->regs + INTELXVF_RD + INTEL_xDCTL );
275
+		writel ( rxdctl, intel->regs + INTELXVF_RD(0) + INTEL_xDCTL );
266 276
 	}
267 277
 
268 278
 	/* Create transmit descriptor ring */
@@ -283,9 +293,12 @@ static int intelxvf_open ( struct net_device *netdev ) {
283 293
 	/* Configure receive buffer sizes and set receive descriptor type */
284 294
 	srrctl = readl ( intel->regs + INTELXVF_SRRCTL );
285 295
 	srrctl &= ~( INTELXVF_SRRCTL_BSIZE_MASK |
296
+		     INTELXVF_SRRCTL_BHDRSIZE_MASK |
286 297
 		     INTELXVF_SRRCTL_DESCTYPE_MASK );
287 298
 	srrctl |= ( INTELXVF_SRRCTL_BSIZE_DEFAULT |
288
-		    INTELXVF_SRRCTL_DESCTYPE_DEFAULT );
299
+		    INTELXVF_SRRCTL_BHDRSIZE_DEFAULT |
300
+		    INTELXVF_SRRCTL_DESCTYPE_DEFAULT |
301
+		    INTELXVF_SRRCTL_DROP_EN );
289 302
 	writel ( srrctl, intel->regs + INTELXVF_SRRCTL );
290 303
 
291 304
 	/* Clear "must-be-zero" bit for direct cache access (DCA).  We
@@ -434,9 +447,9 @@ static int intelxvf_probe ( struct pci_device *pci ) {
434 447
 	netdev->dev = &pci->dev;
435 448
 	memset ( intel, 0, sizeof ( *intel ) );
436 449
 	intel_init_mbox ( &intel->mbox, INTELXVF_MBCTRL, INTELXVF_MBMEM );
437
-	intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTELXVF_TD,
450
+	intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTELXVF_TD(0),
438 451
 			  intel_describe_tx_adv );
439
-	intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTELXVF_RD,
452
+	intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTELXVF_RD(0),
440 453
 			  intel_describe_rx );
441 454
 
442 455
 	/* Fix up PCI device */

+ 12
- 2
src/drivers/net/intelxvf.h View File

@@ -55,8 +55,11 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
55 55
 /** Mailbox Control Register */
56 56
 #define INTELXVF_MBCTRL 0x02fcUL
57 57
 
58
+/** Packet Split Receive Type */
59
+#define INTELXVF_PSRTYPE 0x0300UL
60
+
58 61
 /** Receive Descriptor register block */
59
-#define INTELXVF_RD 0x1000UL
62
+#define INTELXVF_RD(n) ( 0x1000UL + ( 0x40 * (n) ) )
60 63
 
61 64
 /** RX DCA Control Register */
62 65
 #define INTELXVF_DCA_RXCTRL 0x100cUL
@@ -67,9 +70,13 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
67 70
 #define INTELXVF_SRRCTL_BSIZE(kb) ( (kb) << 0 )	/**< Receive buffer size */
68 71
 #define INTELXVF_SRRCTL_BSIZE_DEFAULT INTELXVF_SRRCTL_BSIZE ( 0x02 )
69 72
 #define INTELXVF_SRRCTL_BSIZE_MASK INTELXVF_SRRCTL_BSIZE ( 0x1f )
73
+#define INTELXVF_SRRCTL_BHDRSIZE(kb) ( (kb) << 8 ) /**< Header size */
74
+#define INTELXVF_SRRCTL_BHDRSIZE_DEFAULT INTELXVF_SRRCTL_BHDRSIZE ( 0x04 )
75
+#define INTELXVF_SRRCTL_BHDRSIZE_MASK INTELXVF_SRRCTL_BHDRSIZE ( 0x0f )
70 76
 #define INTELXVF_SRRCTL_DESCTYPE(typ) ( (typ) << 25 ) /**< Descriptor type */
71 77
 #define INTELXVF_SRRCTL_DESCTYPE_DEFAULT INTELXVF_SRRCTL_DESCTYPE ( 0x00 )
72 78
 #define INTELXVF_SRRCTL_DESCTYPE_MASK INTELXVF_SRRCTL_DESCTYPE ( 0x07 )
79
+#define INTELXVF_SRRCTL_DROP_EN 0x10000000UL
73 80
 
74 81
 /** Good Packets Received Count */
75 82
 #define INTELXVF_GPRC 0x101c
@@ -84,7 +91,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
84 91
 #define INTELXVF_MPRC 0x1034
85 92
 
86 93
 /** Transmit Descriptor register block */
87
-#define INTELXVF_TD 0x2000UL
94
+#define INTELXVF_TD(n) ( 0x2000UL + ( 0x40 * (n) ) )
88 95
 
89 96
 /** Good Packets Transmitted Count */
90 97
 #define INTELXVF_GPTC 0x201c
@@ -101,4 +108,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
101 108
 /** API version 1.1 */
102 109
 #define INTELXVF_MSG_VERSION_1_1 0x00000002UL
103 110
 
111
+/** Number of queues */
112
+#define INTELXVF_NUM_RINGS 8
113
+
104 114
 #endif /* _INTELXVF_H */

Loading…
Cancel
Save