[ipxe-devel] [PATCH 1/1] [intelxvf] Reset all vf settings before config

Vishvananda Ishaya Abrams vish.ishaya at oracle.com
Fri Dec 2 21:56:03 UTC 2016


From: Vishvananda Ishaya <vish.ishaya at oracle.com>

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.
---
 src/drivers/net/intel.c    | 25 +++++++++++++++++++++++++
 src/drivers/net/intel.h    |  2 ++
 src/drivers/net/intelxvf.c | 17 ++++++++++++++++-
 src/drivers/net/intelxvf.h |  9 ++++++++-
 4 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/src/drivers/net/intel.c b/src/drivers/net/intel.c
index 4f8a4cb..626a0c3 100644
--- a/src/drivers/net/intel.c
+++ b/src/drivers/net/intel.c
@@ -477,6 +477,31 @@ int intel_create_ring ( struct intel_nic *intel, struct intel_ring *ring ) {
 }
 
 /**
+ * Clear descriptor
+ *
+ * @v intel		Intel device
+ * @v reg			Descriptor register offset
+ */
+void intel_clear_descriptor ( struct intel_nic *intel, unsigned int reg ) {
+	/* Disable ring */
+	writel ( 0, intel->regs + reg + INTEL_xDCTL );
+
+	while ( (readl ( intel->regs + reg + INTEL_xDCTL ) & INTEL_xDCTL_ENABLE) != 0 )
+		DBGC ( intel, "WAITING FOR RXD RESET\n" );
+
+	/* Clear ring length */
+	writel ( 0, ( intel->regs + reg + INTEL_xDLEN ) );
+
+	/* Clear ring address */
+	writel ( 0, intel->regs + reg + INTEL_xDBAH );
+	writel ( 0, intel->regs + reg + INTEL_xDBAL );
+
+	/* Reset head and tail pointers */
+	writel ( 0, ( intel->regs + reg + INTEL_xDH ) );
+	writel ( 0, ( intel->regs + reg + INTEL_xDT ) );
+}
+
+/**
  * Destroy descriptor ring
  *
  * @v intel		Intel device
diff --git a/src/drivers/net/intel.h b/src/drivers/net/intel.h
index 16a72a1..836c69c 100644
--- a/src/drivers/net/intel.h
+++ b/src/drivers/net/intel.h
@@ -332,6 +332,8 @@ extern void intel_describe_rx ( struct intel_descriptor *rx,
 				physaddr_t addr, size_t len );
 extern int intel_create_ring ( struct intel_nic *intel,
 			       struct intel_ring *ring );
+extern void intel_clear_descriptor ( struct intel_nic *intel,
+			       unsigned int reg );
 extern void intel_destroy_ring ( struct intel_nic *intel,
 				 struct intel_ring *ring );
 extern void intel_refill_rx ( struct intel_nic *intel );
diff --git a/src/drivers/net/intelxvf.c b/src/drivers/net/intelxvf.c
index 91a10b1..f25f334 100644
--- a/src/drivers/net/intelxvf.c
+++ b/src/drivers/net/intelxvf.c
@@ -218,6 +218,7 @@ static int intelxvf_open ( struct net_device *netdev ) {
 	uint32_t dca_rxctrl;
 	int vlan_thing;
 	int rc;
+	int i;
 
 	/* Reset the function */
 	intelxvf_reset ( intel );
@@ -252,6 +253,15 @@ static int intelxvf_open ( struct net_device *netdev ) {
 		goto err_mbox_set_mtu;
 	}
 
+	/* Clear descriptor rings */
+	for ( i = 0; i < 8; i ++ ) {
+		intel_clear_descriptor ( intel, INTELXVF_TD + i * 0x40 );
+		intel_clear_descriptor ( intel, INTELXVF_RD + i * 0x40 );
+	}
+
+	/* Reset packet split receive type register */
+	writel ( 0, intel->regs + INTELXVF_PSRTYPE );
+
 	/* Get queue configuration.  Ignore failures, since the host
 	 * may not support this message.
 	 */
@@ -283,9 +293,14 @@ static int intelxvf_open ( struct net_device *netdev ) {
 	/* Configure receive buffer sizes and set receive descriptor type */
 	srrctl = readl ( intel->regs + INTELXVF_SRRCTL );
 	srrctl &= ~( INTELXVF_SRRCTL_BSIZE_MASK |
+		     INTELXVF_SRRCTL_BHDRSIZE_MASK |
 		     INTELXVF_SRRCTL_DESCTYPE_MASK );
 	srrctl |= ( INTELXVF_SRRCTL_BSIZE_DEFAULT |
-		    INTELXVF_SRRCTL_DESCTYPE_DEFAULT );
+		    INTELXVF_SRRCTL_BHDRSIZE_DEFAULT |
+		    INTELXVF_SRRCTL_DESCTYPE_DEFAULT |
+		    INTELXVF_SRRCTL_DROP_EN );
+
+
 	writel ( srrctl, intel->regs + INTELXVF_SRRCTL );
 
 	/* Clear "must-be-zero" bit for direct cache access (DCA).  We
diff --git a/src/drivers/net/intelxvf.h b/src/drivers/net/intelxvf.h
index ad046a6..14f0edc 100644
--- a/src/drivers/net/intelxvf.h
+++ b/src/drivers/net/intelxvf.h
@@ -55,6 +55,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 /** Mailbox Control Register */
 #define INTELXVF_MBCTRL 0x02fcUL
 
+/** Packet Split Receive Type */
+#define INTELXVF_PSRTYPE 0x0300UL
+
 /** Receive Descriptor register block */
 #define INTELXVF_RD 0x1000UL
 
@@ -65,11 +68,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 /** Split Receive Control Register */
 #define INTELXVF_SRRCTL 0x1014UL
 #define INTELXVF_SRRCTL_BSIZE(kb) ( (kb) << 0 )	/**< Receive buffer size */
-#define INTELXVF_SRRCTL_BSIZE_DEFAULT INTELXVF_SRRCTL_BSIZE ( 0x02 )
+#define INTELXVF_SRRCTL_BSIZE_DEFAULT INTELXVF_SRRCTL_BSIZE ( 0x02 ) /* 2 Kbytes */
 #define INTELXVF_SRRCTL_BSIZE_MASK INTELXVF_SRRCTL_BSIZE ( 0x1f )
+#define INTELXVF_SRRCTL_BHDRSIZE(kb) ( (kb) << 8 )	/**< Header size */
+#define INTELXVF_SRRCTL_BHDRSIZE_DEFAULT INTELXVF_SRRCTL_BHDRSIZE ( 0x4 ) /* 256 bytes */
+#define INTELXVF_SRRCTL_BHDRSIZE_MASK INTELXVF_SRRCTL_BHDRSIZE ( 0xf )
 #define INTELXVF_SRRCTL_DESCTYPE(typ) ( (typ) << 25 ) /**< Descriptor type */
 #define INTELXVF_SRRCTL_DESCTYPE_DEFAULT INTELXVF_SRRCTL_DESCTYPE ( 0x00 )
 #define INTELXVF_SRRCTL_DESCTYPE_MASK INTELXVF_SRRCTL_DESCTYPE ( 0x07 )
+#define INTELXVF_SRRCTL_DROP_EN 0x10000000
 
 /** Good Packets Received Count */
 #define INTELXVF_GPRC 0x101c
-- 
2.5.0




More information about the ipxe-devel mailing list