Thread (16 messages) flat view 16 messages, 3 authors, 2012-07-12
STALE5143d

[PATCH net-next 01/11] sfc: Implement 128-bit writes for efx_writeo_page

From: Ben Hutchings <hidden>
Date: 2012-07-11 23:15:21
Subsystem: networking drivers, sfc network driver, the rest · Maintainers: Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Edward Cree, Linus Torvalds

Add support for writing a TX descriptor to the NIC in one PCIe
transaction on x86_64 machines.

Signed-off-by: Ben Hutchings <redacted>
---
 drivers/net/ethernet/sfc/bitfield.h |    5 +++
 drivers/net/ethernet/sfc/io.h       |   51 +++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/sfc/bitfield.h b/drivers/net/ethernet/sfc/bitfield.h
index b26a954..8f8af3e 100644
--- a/drivers/net/ethernet/sfc/bitfield.h
+++ b/drivers/net/ethernet/sfc/bitfield.h
@@ -69,6 +69,10 @@
 	((width) == 32 ? ~((u32) 0) :		\
 	 (((((u32) 1) << (width))) - 1))
 
+typedef struct {
+        __le64 b, a;
+} efx_le_128;
+
 /* A doubleword (i.e. 4 byte) datatype - little-endian in HW */
 typedef union efx_dword {
 	__le32 u32[1];
@@ -83,6 +87,7 @@ typedef union efx_qword {
 
 /* An octword (eight-word, i.e. 16 byte) datatype - little-endian in HW */
 typedef union efx_oword {
+	efx_le_128 u128;
 	__le64 u64[2];
 	efx_qword_t qword[2];
 	__le32 u32[4];
diff --git a/drivers/net/ethernet/sfc/io.h b/drivers/net/ethernet/sfc/io.h
index 751d1ec..0868aef 100644
--- a/drivers/net/ethernet/sfc/io.h
+++ b/drivers/net/ethernet/sfc/io.h
@@ -57,10 +57,57 @@
  *   current state.
  */
 
+#ifdef CONFIG_X86_64
+#define EFX_USE_SSE_IO 1
+#endif
+
 #if BITS_PER_LONG == 64
 #define EFX_USE_QWORD_IO 1
 #endif
 
+#ifdef EFX_USE_SSE_IO
+
+static inline void _efx_writeo(struct efx_nic *efx, efx_le_128 value,
+			       unsigned int reg)
+{
+	unsigned long cr0;
+	efx_le_128 xmm_save[1];
+	void __iomem *addr = efx->membase + reg;
+
+	preempt_disable();
+
+	/* Save the xmm0 register to stack */
+	asm volatile(
+		"movq %%cr0,%0          ;\n\t"
+		"clts                   ;\n\t"
+		"movups %%xmm0,(%1)     ;\n\t"
+		: "=&r" (cr0)
+		: "r" (xmm_save)
+		: "memory");
+
+	/* First read the data into register xmm0
+	 * Then write this out to the address that was given
+	 */
+	asm volatile(
+		"movdqu %1,%%xmm0       ;\n\t"
+		"movdqa %%xmm0,%0       ;\n\t"
+		: "=m" (*(unsigned long __force *)addr)
+		: "m" (value)
+		: "memory");
+
+	/* Restore the xmm0 register */
+	asm volatile(
+		"sfence                 ;\n\t"
+		"movups (%1),%%xmm0     ;\n\t"
+		"movq   %0,%%cr0        ;\n\t"
+		:
+		: "r" (cr0), "r" (xmm_save)
+		: "memory");
+
+	preempt_enable();
+}
+#endif /* EFX_USE_SSE_IO */
+
 #ifdef EFX_USE_QWORD_IO
 static inline void _efx_writeq(struct efx_nic *efx, __le64 value,
 				  unsigned int reg)
@@ -235,6 +282,9 @@ static inline void _efx_writeo_page(struct efx_nic *efx, efx_oword_t *value,
 		   "writing register %x with " EFX_OWORD_FMT "\n", reg,
 		   EFX_OWORD_VAL(*value));
 
+#ifdef EFX_USE_SSE_IO
+	_efx_writeo(efx, value->u128, reg + 0);
+#else
 #ifdef EFX_USE_QWORD_IO
 	_efx_writeq(efx, value->u64[0], reg + 0);
 	_efx_writeq(efx, value->u64[1], reg + 8);
@@ -244,6 +294,7 @@ static inline void _efx_writeo_page(struct efx_nic *efx, efx_oword_t *value,
 	_efx_writed(efx, value->u32[2], reg + 8);
 	_efx_writed(efx, value->u32[3], reg + 12);
 #endif
+#endif
 }
 #define efx_writeo_page(efx, value, reg, page)				\
 	_efx_writeo_page(efx, value,					\
-- 
1.7.7.6



-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help