]> Pileus Git - ~andy/linux/blobdiff - include/linux/etherdevice.h
kfifo: fix kfifo_alloc() to return a signed int value
[~andy/linux] / include / linux / etherdevice.h
index 2308fbb4523a399abce0809860f6f398c8844ed5..f16a01081e150035438dfc886d15943a79085a00 100644 (file)
@@ -71,7 +71,7 @@ static inline int is_zero_ether_addr(const u8 *addr)
  */
 static inline int is_multicast_ether_addr(const u8 *addr)
 {
-       return (0x01 & addr[0]);
+       return 0x01 & addr[0];
 }
 
 /**
@@ -82,7 +82,7 @@ static inline int is_multicast_ether_addr(const u8 *addr)
  */
 static inline int is_local_ether_addr(const u8 *addr)
 {
-       return (0x02 & addr[0]);
+       return 0x02 & addr[0];
 }
 
 /**
@@ -237,13 +237,29 @@ static inline bool is_etherdev_addr(const struct net_device *dev,
  * entry points.
  */
 
-static inline int compare_ether_header(const void *a, const void *b)
+static inline unsigned long compare_ether_header(const void *a, const void *b)
 {
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
+       unsigned long fold;
+
+       /*
+        * We want to compare 14 bytes:
+        *  [a0 ... a13] ^ [b0 ... b13]
+        * Use two long XOR, ORed together, with an overlap of two bytes.
+        *  [a0  a1  a2  a3  a4  a5  a6  a7 ] ^ [b0  b1  b2  b3  b4  b5  b6  b7 ] |
+        *  [a6  a7  a8  a9  a10 a11 a12 a13] ^ [b6  b7  b8  b9  b10 b11 b12 b13]
+        * This means the [a6 a7] ^ [b6 b7] part is done two times.
+       */
+       fold = *(unsigned long *)a ^ *(unsigned long *)b;
+       fold |= *(unsigned long *)(a + 6) ^ *(unsigned long *)(b + 6);
+       return fold;
+#else
        u32 *a32 = (u32 *)((u8 *)a + 2);
        u32 *b32 = (u32 *)((u8 *)b + 2);
 
        return (*(u16 *)a ^ *(u16 *)b) | (a32[0] ^ b32[0]) |
               (a32[1] ^ b32[1]) | (a32[2] ^ b32[2]);
+#endif
 }
 
 #endif /* _LINUX_ETHERDEVICE_H */